图论-有向图的拓扑排序

(1)、有向图,边是有方向的。

邻接矩阵表示方法上下三角形是不对称的。在添加一条边是只需要一条语句,

    //添加一个边

    public void addEdge(int start,int end){

   
adjMat[start][end] = 1;

    }

(2)、有向图的算法-拓扑排序

有向图的应用,某些项目或者事件必须按照特定的顺序排序或发生。

比如大学课程安排,要想得到学位需要必修那些课程。每年的课程都按先后关系排序,全部必修完毕,最后才能答辩,拿到学位。

拓扑排序的步骤:

(1)、找到一个没有后继的顶点(如果有一条边从A指向B,那么B是A的后继)。

(2)、从图中删除这个顶点,在列表的前面插入顶点的标记。

(3)、重复步骤1和2.直到所有的顶点都从图中删除。这时列表显示的顶点顺序就是拓扑排序的结果。

环:环图是不能进行拓扑排序的,如果有N个顶点的有向图有超过N-1条边,那么必定存在环。

Graph_topo.java

package com.mapbar.structure;

/**
 * 
 * Class Graph_topo
 * 
 * Description 有向图的拓扑排序
 * 
 * Company mapbar
 * 
 * author Chenll E-mail: Chenll@mapbar.com
 * 
 * Version 1.0
 * 
 * Date 2011-11-17 下午03:38:27
 */

//定义节点
class Vertex{
	public char label;
	
	public boolean isVisited;
	
	public Vertex(char label){
		this.label = label;
		this.isVisited = false;
	}
}

public class Graph_topo {
	//顶点数组
	private Vertex[] vArr;
	
	//定义邻接矩阵
	private int[][] adjMat;
	
	 //顶点的最大数目 
    private int maxSize; 
    
     //当前顶点 下标
    private int currVertex;
    
    private char[] sortedArr;
    
    //构造方法
    public Graph_topo(int maxSize){
    	sortedArr = new char[maxSize];
    	this.maxSize = maxSize;
    	vArr = new Vertex[maxSize];
    	adjMat = new int[maxSize][maxSize];
    	for (int i = 0; i<adjMat.length; i++){
    		for(int j = 0; j<adjMat.length; j++){
    			adjMat[i][j] = 0;
    		}
    	}
    	currVertex = 0;
    }
    
    //添加一个顶点
    public void addVertex(char label){
    	vArr[currVertex++] = new Vertex(label);
    }
    
    //添加一个边
    public void addEdge(int start,int end){
    	adjMat[start][end] = 1;
    }
    
    //显示一个顶点
    public void disVertex(int v){
    	System.out.print(vArr[v].label+",");
    }
    
    //拓扑排序
   public void topo(){
	   int orig_nVert = currVertex;
	   while(currVertex>0){
		   int cuVertex = noSuc();
		   if(currVertex==-1){
			   System.out.println("图中有环路,不能进行拓扑排序");
			   return;
		   }
		   sortedArr[currVertex-1] = vArr[cuVertex].label;
		   deleteVertex(cuVertex);
	   }
	   disAllVertex(orig_nVert);
   }
   
   //找一个没有后继结点
   public int noSuc(){
	   boolean isEdge;
	   for(int i = 0; i<currVertex; i++){
		   isEdge = false;
		   for(int j = 0; j<currVertex; j++){
			   if(adjMat[i][j]>0){
				   isEdge = true;
				   break;
			   }
		   }
		   if(!isEdge){
			   return i;
		   }
	   }
	   return -1;
   }
   
   //删除顶点,后面的顶点向前移动,同时行和列从矩阵中删除,下面的行和右边的列
   public void deleteVertex(int delV){
	   if(delV != currVertex-1){
		   //删除顶点
		   for(int j = delV; j<currVertex; j++){
			   vArr[j] = vArr[j+1];
		   }
		   
		   //删除顶点所在的邻接矩阵
		   //上移
		   for(int row = delV; row<currVertex-1; row++){
			   for(int col = 0; col<currVertex;col++){
				   adjMat[row][col] = adjMat[row+1][col];
			   }
		   }
		   
		   //左移
		   for(int col = delV; col<currVertex-1; col++){
			   for(int row = 0; row<currVertex;row++){
				   adjMat[row][col] = adjMat[row][col+1];
			   }
		   }
		   
	   }
	   currVertex--;
   }
   
	//显示拓扑排序的结果
	public void disAllVertex(int org_length){
		for(int j = 0; j<org_length; j++){
			System.out.print(sortedArr[j]+",");
		}
	}
	   
    //主调函数
    public static void main(String[] args){
    	Graph_topo g = new Graph_topo(10);
    	g.addVertex('a');
    	g.addVertex('b');
    	g.addVertex('c');
    	g.addVertex('d');
    	g.addVertex('e');
    	g.addVertex('f');   	
    	g.addEdge(0,1);
    	g.addEdge(0,2);
    	g.addEdge(1,3);
    	g.addEdge(4,5);
    	g.addEdge(5,1);
    	g.topo();
    }
}

《图论-有向图的拓扑排序》

output:

e,f,a,b,d,c,

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/cdl2008sky/article/details/6981938
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞