获取图顶点的入度、出度;获取图的两个顶点之间的权值; 图的深度优先算法、图的广度优先遍历

在这里插入图片描述
广度优先结果:
在这里插入图片描述
深度优先结果:

在这里插入图片描述
代码整理:

public class Graph {
	private int vertexSize;//顶点数量
	private int[] vertexs;//顶点数组
	private int[][] matrix;    //矩阵
	private static final int MAX_WEIGHT=1000;
	
	//
	private boolean[] isVisited;
	
	//初始化顶点数量、二维矩阵和顶点数组
	public Graph(int vertextSize){
		this.vertexSize=vertextSize;
		matrix=new int[vertexSize][vertexSize];	
		
		vertexs=new int[vertextSize];
		for(int i=0;i<vertextSize;i++){
			vertexs[i]=i;
		}
		
		isVisited=new boolean[vertexSize];
		
	}
			
	public int[] getVertexs() {
		return vertexs;
	}

	public void setVertexs(int[] vertexs) {
		this.vertexs = vertexs;
	}

	/*  
	 * 根据下标获取指定顶点,然后求得指定顶点的出度 
	 * (出度看二维矩阵的横排)   (求入度看二维矩阵的纵排)
	 */
	public  int getOutDegree(int index){ 
		int degree=0;
		
		//遍历得到权值
		for(int j=0;j<matrix[index].length;j++){//v0->v0 v0>v1 v0->v2 v0->v3 v0->v4
			int weight=matrix[index][j];   
			if(weight != 0 && weight != MAX_WEIGHT){   //说明该节点是有度的
				degree++;
			}
		}
		return degree;
	}
	
	/*
	 * 获取顶点的入度  (求入度看二维矩阵的纵排)
	 */
	public int getInDegree(int index){
		int degree=0;
		for(int k=0;k<matrix[index].length;k++){
			int weight = matrix[k][index];
			if(weight != 0 && weight != MAX_WEIGHT){
				degree++;
			}
		}
		
		return degree;
	}
	
	
	/*
	 * 获取两个顶点之间的权值
	 */
	public int getWeight(int v1,int v2){
		int weight=matrix[v1][v2];
		return weight == 0 ? 0 : (weight == MAX_WEIGHT ? -1 : weight);
	}
	
	/*
	 * 获取某个顶点的第一个临节点
	 */
	public int getFirstNeighbor(int index){
		for(int j=0;j<vertexSize;j++){
			if(matrix[index][j] > 0 && matrix[index][j]<MAX_WEIGHT){
				return j;
			}
		}
		return -1;
	}
	
	/*
	 * 上一步骤中获取到了某个顶点的第一个临节点,记录他的下标,然后根据他的下标来取得下一个临节点
	 * v:表示要找的顶点
	 * index:表示该顶点相对于哪个临节点去获取下一个临节点
	 */
	public int getNextNeighbor(int v,int index){
		for(int j=index+1;j<vertexSize;j++){       
			if(matrix[v][j] >0 && matrix[v][j] < MAX_WEIGHT){
				return j;
			}
		}     //由v7执行到这里,也就是v7再也没有满足要求的临节点了  return -1
		return -1;
	}
	
	/*
	 * 图的深度优先算法
	 */
	public void depthFirstSearch(int i){
		isVisited[i]=true;  //第一次进来,则该顶点被访问过
		
		int w = getFirstNeighbor(i); //比如i为0,找到第一个顶点的第一个临节点的下标为w
		
		while(w != -1){  //临节点存在
			         //继续往下深度遍历
			
			if(!isVisited[w]){ //v0->v1->v2->v3->v4->v5 找v5的临节点,为了防止v5再找到v0
						//需要遍历	该顶点
				System.out.println("访问到了:"+w+"顶点");
				depthFirstSearch(w);
				
			}         //以v1举例:v1的第一个临节点为v0,但v0已经被访问过了,于是不执行if语句
								//也就是执行下面的语句:根据i节点  经由 w去找i的下一个临节点
			w=getNextNeighbor(i, w);
		}
	}
	
	/*如果图是不连通的,存在有顶点不被遍历的情况,这里通过for循环强制遍历每个顶点
	 * 对外公开的深度优先遍历
	 */
	public void depthFirstSearch(){
		isVisited=new boolean[vertexSize];
		for(int i=0;i<vertexSize;i++){
			if(!isVisited[i]){
				System.out.println("访问到了: "+i+"顶点");
				depthFirstSearch(i);
			}
		}
		
		isVisited=new boolean[vertexSize];
	}
	
	public static void main(String[] args) {
		Graph graph = new Graph(9);
		
		int [] a1 = new int[]{0,10,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT};
		int [] a2 = new int[]{10,0,18,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,MAX_WEIGHT,12};
		int [] a3 = new int[]{MAX_WEIGHT,MAX_WEIGHT,0,22,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,8};
		int [] a4 = new int[]{MAX_WEIGHT,MAX_WEIGHT,22,0,20,MAX_WEIGHT,MAX_WEIGHT,16,21};
		int [] a5 = new int[]{MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,20,0,26,MAX_WEIGHT,7,MAX_WEIGHT};
		int [] a6 = new int[]{11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,26,0,17,MAX_WEIGHT,MAX_WEIGHT};
		int [] a7 = new int[]{MAX_WEIGHT,16,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,17,0,19,MAX_WEIGHT};
		int [] a8 = new int[]{MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,7,MAX_WEIGHT,19,0,MAX_WEIGHT};
		int [] a9 = new int[]{MAX_WEIGHT,12,8,21,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,0};
		
		graph.matrix[0] = a1;
		graph.matrix[1] = a2;
		graph.matrix[2] = a3;
		graph.matrix[3] = a4;
		graph.matrix[4] = a5;
		graph.matrix[5] = a6;
		graph.matrix[6] = a7;
		graph.matrix[7] = a8;
		graph.matrix[8] = a9;
		
		//获取指定顶点的出度
		int degree=graph.getOutDegree(2);
		System.out.println("V2的出度:"+degree);
		
		int inDegree=graph.getInDegree(2);
		System.out.println("V2的入度:"+inDegree);
		
		//获取两个顶点之间的权值
		//int value=graph.getWeight(2, 3);
		//System.out.println("v2与v3之间的权值为: "+value);
		
		/*
		 * 图的深度优先遍历
		 */
		//graph.depthFirstSearch();
		
		/*
		 * 图的广度优先遍历
		 */
		graph.broadFirstSearch();
		
	}
	
	/*
	 * 非连通图情况下  强制遍历
	 */
	public void broadFirstSearch(){
		isVisited=new boolean[vertexSize];
		for(int i=0;i<vertexSize;i++){
			if(!isVisited[i]){
				broadFirstSearch(i);
			}
		}
	}

	/*
	 * 实现广度优先遍历   LinkedList实现了Queue接口
	 */
	private void broadFirstSearch(int i) {
		int u,w;
		LinkedList<Integer> queue=new LinkedList<Integer>();
		
		System.out.println("访问到了: "+i+"顶点");
		isVisited[i]=true;
		queue.add(i);  //第一次把v0加到队列
		
		while(!queue.isEmpty()){
			u = (Integer)(queue.removeFirst()).intValue();
			w = getFirstNeighbor(u);
			
			while(w != -1){
				
				if(!isVisited[w]){
					System.out.println("访问到了: "+w+"顶点");
					isVisited[w]=true;
					queue.add(w);
				}
				
				w=getNextNeighbor(u, w);
			}
			
		}
	}
	
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值