图(有向)-拓扑排序
具有优先关系的情况
有向图的邻接矩阵不是双向的
具有这样的规则:在某个顶点输出之前,有些顶点必须先输出。
在图中先找到没有后继顶点的顶点,存入数组中,然后删除。如此循环
//图的顶点 public class Vertex { public char label;//顶点的标识符 public Vertex(char lab) {//初始化顶点(属性) label=lab; } }
public class Graph { private final int MAX_VERTS=20;//最大顶点数 private Vertex[] vertexList;//顶点数组 private int [][]adjMat;//顶点关系的领接矩阵(邻接矩阵的每行或者每列的位置跟顶点数组是对应的) private int nVerts;//当前顶点个数 private char[] sortedArray;//用于存放获取到的顶点数组的值(拓扑排序后的结果) public Graph() {//初始化图 vertexList=new Vertex[MAX_VERTS]; //初始化顶点数组 adjMat=new int [MAX_VERTS][MAX_VERTS] ;//初始化邻接矩阵 for(int j=0;j<MAX_VERTS;j++) for(int i=0;i<MAX_VERTS;i++) adjMat[i][j]=0; nVerts=0;//初始化当前顶点个数 sortedArray=new char[MAX_VERTS]; } //向顶点数组中添加顶点对象 public void addVertex(char lab) { vertexList[nVerts++]=new Vertex(lab);//建立lab对象,往数组内添加 } //添加边(向邻接矩阵中改变数据为1) public void addEdge(int start,int end) { //因为是有向图所以(i,j)要添加1 adjMat[start][end]=1; } //打印顶点数组,根据获取的顶点数组的下标值,打印顶点 public void displayVertex(int v) { System.out.print(vertexList[v].label); } //拓扑排序 public void topo() { int orig_nVerts=nVerts;//记下最初图的顶点数 while(nVerts>0) {//循环条件,如果图中的顶点数为0,就退出循环 int currentVertex=noSuccessorts(); if(currentVertex==-1) { System.out.println("没有存在后继顶点的顶点了 "); return ; } //将没有后继顶点的数据存入数组中(从后开始存) sortedArray[nVerts-1]=vertexList[currentVertex].label; //删除该顶点 deleteVertx(currentVertex); } for(int i=0;i<orig_nVerts;i++) System.out.print(sortedArray[i]); System.out.println(); } //查找一个没有后继顶点的顶点 public int noSuccessorts() { boolean isEdge;//用于循环查找邻接矩阵过程中的标志 for(int row=0;row<nVerts;row++) {//遍历邻接矩阵,查找没有后继顶点的顶点(当前行都为0,那就是了) isEdge=false;//是true说明该顶点不是要找的,是false,说明当前顶点没有后继 for(int col=0; col<nVerts;col++) { if(adjMat[row][col]>0) { isEdge=true; break;//退出内层循环,因为只要存在一个就不是要找的顶点 } } if(!isEdge) return row; } return -1;//说明整个循环都没有找到一个 } //删除一个顶点(需要改变邻接矩阵和顶点顶点数组) public void deleteVertx(int delVert) { if(delVert!=(nVerts-1)) {//如果这个顶点的位置在二维矩阵中是最后一行,删得很简单 for(int j=delVert;j<nVerts-1;j++)//删除顶点数组中的一个值 vertexList[j]=vertexList[j+1]; //删除邻接矩阵中的一行一列 for(int row=delVert;row<nVerts-1;row++) moveRowUp(row,nVerts); for(int col=delVert;col<nVerts-1;col++) moveColLeft(col,nVerts-1); } nVerts--;//删除后需要将当前顶点数减去1,而且这个也是邻接矩阵最后一行的删除方法。 } //移动矩阵中的行一次 private void moveRowUp(int row,int length) { for(int col=0;col<length;col++) adjMat[row][col]=adjMat[row+1][col]; } //移动矩阵中列一次 private void moveColLeft(int col,int length) { for(int row=0;row<length;row++) adjMat[row][col]=adjMat[row][col+1]; } }
public class Test { public static void main(String[] agrs) { Graph theGraph=new Graph();//创建一个图 theGraph.addVertex('A');//添加顶点 theGraph.addVertex('B');//添加顶点 theGraph.addVertex('C');//添加顶点 theGraph.addVertex('D');//添加顶点 theGraph.addVertex('E');//添加顶点 theGraph.addVertex('F');//添加顶点 theGraph.addVertex('G');//添加顶点 theGraph.addVertex('H');//添加顶点 theGraph.addEdge(0, 4);//添加边 theGraph.addEdge(0, 3);//添加边 theGraph.addEdge(1, 4);//添加边 theGraph.addEdge(2, 5);//添加边 theGraph.addEdge(3, 6);//添加边 theGraph.addEdge(4, 6);//添加边 theGraph.addEdge(5, 7);//添加边 theGraph.addEdge(6, 7);//添加边 theGraph.topo(); } }