Java实现图结构

本学期有一门课程叫做算法分析与设计,用的教材是机械工业出版社的《算法导论》中文版第三版。课程只包括这本书的图算法部分,也就是第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;
			
		}
	}

	@Override
	public int numberOfVertices() {
		// TODO Auto-generated method stub
		return n;
	}

	@Override
	public int numberOfEdges() {
		// TODO Auto-generated method stub
		return e;
	}

	@Override
	public boolean exitsEdge(int i, int j) {
		// TODO Auto-generated method stub
		if(i<1 || j<1 || i>n || j>n || aList[i].indexOf(j)==-1)
			return false;
		else
			return true;
	}
	

	@Override
	public void eraseEdge(int n1, int n2) {
		// TODO Auto-generated method stub
		if(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;
	}

	@Override
	public int degree(int n) {
		// TODO Auto-generated method stub
		if(directed()){
			return 0;
		}else{
			if(checkVertex(n))
				return aList[n].size();
			return 0;
		}
	}

	@Override
	public int inDrgree(int vv) {
		// TODO Auto-generated method stub
		if(directed()){
			if(checkVertex(vv)){
				int sum = 0;
				for(int j = 1;j<=n;j++)
					if(aList[j].contains(vv))
						sum++;
				return sum;
			}else
				return 0;
		}else{
			return 0;
		}
	}

	@Override
	public int outDegree(int vn) {
		// TODO Auto-generated method stub
		if(directed()){
			if(checkVertex(vn))
				return aList[vn].size();
			return 0;
		}else
			return 0;
	}

	@Override
	public boolean directed() {
		// TODO Auto-generated method stub
		return directed;
	}

	@Override
	public boolean weighted() {
		// TODO Auto-generated method stub
		return weighted;
	}

	@Override
	/**
	 * 插入一条新的边
	 */
	public boolean insertEdge(edge e) {
		// TODO Auto-generated method stub
		int 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 stub

		RandomGraph 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);
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值