Java实现图结构

来源:互联网 发布:欧洲经济一体化数据 编辑:程序博客网 时间:2024/06/10 13:56

本学期有一门课程叫做算法分析与设计,用的教材是机械工业出版社的《算法导论》中文版第三版。课程只包括这本书的图算法部分,也就是第22章到第26章的部分,授课老师是郭炅老师,郭老师的水平还是很高的,在这里对郭老师一学期的授课表示感谢。而这几篇关于图算法的博客,就是基于这门课程的实验来进行整理的。

我们知道图一般有两种表示方法:邻接链表和邻接矩阵。比如在下图中b与c分别是图a的邻接链表表示和邻接矩阵表示。

这第一个实验是很简单的,就是要求生成两个随机的图,一个有向图一个无向图。有向图两千条边左右,无向图一千条边左右,边的数量是大概的。100个顶点。要求能算出每个顶点的度。要求每次图是随机生成的,并且有良好的结构。这里要求的是用邻接链表结构来表示。计算出度和 入度当然也是用遍历邻接链表了。

具体实现代码如下

import java.util.*;/** *  * @author sdu20 * * @param <T> */public class GraphChain extends LinkedList{public GraphChain(){super();}public void insert(int i,int j){add(i,j);}}


import java.util.*;/** * 邻接链表实现 * @author sdu20 * * @param <T> */public class LinkedDigraph<T> extends Graph {private int n;//顶点数private int e;//边数GraphChain[] aList;//邻接表private boolean directed;private boolean weighted;private int[] Reached;public LinkedDigraph(int numberOfVertices,boolean dir){if(numberOfVertices<0){System.out.println("The number of vertices must be >= 0");System.exit(0);}else{n = numberOfVertices;e = 0;aList = new GraphChain[n+1];Reached = new int[n+1];for(int i =1;i<=n;i++){aList[i] = new GraphChain();Reached[i] = 0;}directed = dir;weighted = false;}}public LinkedDigraph(int numberOfVertices,boolean dir,boolean wei){if(numberOfVertices<0){System.out.println("The number of vertices must be >= 0");System.exit(0);}else{n = numberOfVertices;e = 0;aList = new GraphChain[n+1];Reached = new int[n+1];for(int i =1;i<=n;i++){aList[i] = new GraphChain();Reached[i] = 0;}directed = dir;weighted = wei;}}@Overridepublic int numberOfVertices() {// TODO Auto-generated method stubreturn n;}@Overridepublic int numberOfEdges() {// TODO Auto-generated method stubreturn e;}@Overridepublic boolean exitsEdge(int i, int j) {// TODO Auto-generated method stubif(i<1 || j<1 || i>n || j>n || aList[i].indexOf(j)==-1)return false;elsereturn true;}@Overridepublic void eraseEdge(int n1, int n2) {// TODO Auto-generated method stubif(n1>= 1 && n2>=1 && n1<=n && n2<=n){if(aList[n1].contains(n2)){int index = aList[n1].indexOf(n2);aList[n1].remove(index);e--;}}}/** * 检查顶点是否有效 * @param theVertex * @return */public final boolean checkVertex(int theVertex){if(theVertex<1 || theVertex >n)return false;else return true;}@Overridepublic int degree(int n) {// TODO Auto-generated method stubif(directed()){return 0;}else{if(checkVertex(n))return aList[n].size();return 0;}}@Overridepublic int inDrgree(int vv) {// TODO Auto-generated method stubif(directed()){if(checkVertex(vv)){int sum = 0;for(int j = 1;j<=n;j++)if(aList[j].contains(vv))sum++;return sum;}elsereturn 0;}else{return 0;}}@Overridepublic int outDegree(int vn) {// TODO Auto-generated method stubif(directed()){if(checkVertex(vn))return aList[vn].size();return 0;}elsereturn 0;}@Overridepublic boolean directed() {// TODO Auto-generated method stubreturn directed;}@Overridepublic boolean weighted() {// TODO Auto-generated method stubreturn weighted;}@Override/** * 插入一条新的边 */public boolean insertEdge(edge e) {// TODO Auto-generated method stubint v1 = e.getVertex1();int v2 = e.getVertex2();if(v1<1 || v2<1 || v1>n || v2>n ){//System.out.println("Illegal edge.");return false;}//System.out.println(v1);//System.out.println(v2);//System.out.println(aList[v1].indexOf(v2));if(!aList[v1].contains(v2)){aList[v1].insert(0,v2);this.e++;return true;}return false;}public edge getEdge(int v1,int v2){return null;}/** * 输出图 */public void bianli(){if(n==0){System.out.println("Empty");return;}if(directed){if(weighted){System.out.println("共有"+n+"个顶点,"+e+"条边");for(int i = 1;i<=n;i++){System.out.println(i+":"+"入度:"+inDrgree(i)+" 出度:"+outDegree(i)+aList[i].toString());}}else{System.out.println("共有"+n+"个顶点,"+e+"条边");for(int i = 1;i<=n;i++){System.out.println(i+":"+"入度:"+inDrgree(i)+" 出度:"+outDegree(i)+aList[i].toString());}}}else{System.out.println("共有"+n+"个顶点,"+e/2+"条边");for(int i = 1;i<=n;i++){System.out.println(i+":"+"度数:"+degree(i)+aList[i].toString());}}}}


/** * 图的抽象类 * @author sdu20 * * @param <T>对于有权图,T是边上权的数据类型,对于无权图,T是布尔类型 */public abstract class Graph<T> {public Graph(){}public abstract int numberOfVertices();public abstract int numberOfEdges();public abstract boolean exitsEdge(int n1,int n2);public abstract boolean insertEdge(edge<T> e);public abstract void eraseEdge(int n1,int n2);public abstract int degree(int n);public abstract int inDrgree(int n);public abstract int outDegree(int n);public abstract boolean directed();public abstract boolean weighted();}


/** *  * @author sdu20 * * @param <T><T>对于有权图,T是边上权的数据类型,对于无权图,T是布尔类型 */public class edge<T> {private int v1;private int v2;private T weight;public edge(int v1,int v2){this.v1 = v1;this.v2 = v2;}public edge(int v1, int v2, T weight){this.v1 = v1;this.v2 = v2;this.weight = weight;}public void setWeight(T weight){this.weight = weight;}public T getWeight(){return weight;}public int getVertex1(){return v1;}public int getVertex2(){return v2;}}


import java.util.*;/** * 生成一个随机的图 * @author sdu20 * */public class RandomGraph {LinkedDigraph graph;public static void main(String[] args) {// TODO Auto-generated method stubRandomGraph gra = new RandomGraph(true);
//RandomGraph gra = new RandomGraph(false);
gra.bianli();}/** * * @param dir true代表有向图 * false代表无向图 */public RandomGraph(boolean dir){// Scanner in = new Scanner(System.in);// System.out.println("请输入顶点个数:");// int vnum = in.nextInt();graph = new LinkedDigraph(100,dir);if(dir){/** * 有向图 */for(int i = 0;i<2000;i++){int preV = (int)(Math.random()*100+1); int folV = (int)(Math.random()*100+1); edge e = new edge(preV,folV); while(!graph.insertEdge(e)){ preV = (int)(Math.random()*100+1); folV = (int)(Math.random()*100+1); e = new edge(preV,folV); }}}else{/** * 无向图 *///System.out.println("无向图");for(int i = 0;i<1000;i++){int preV=(int)(Math.random()*100+1); int folV=(int)(Math.random()*100+1); edge e1 = new edge(preV,folV); edge e2 = new edge(folV,preV); while(!(graph.insertEdge(e1)&&graph.insertEdge(e2))){ preV=(int)(Math.random()*100+1); folV=(int)(Math.random()*100+1); e1 = new edge(preV,folV); e2 = new edge(folV,preV); }}}}public void bianli(){graph.bianli();}}


运行结果截图如下所示


RandomGraph gra = new RandomGraph(true);
原创粉丝点击