【JAVA】数据结构之拓扑排序

拓扑排序是针对有向图的。

对于环不可进行拓扑排序。

简单理解是不断循环寻找没有后继节点的顶点,将顶点放入数组即可。

(今天不太想认真整理,遇到的问题都注释在代码里了。)

package graph;

public class topo {
	int MAX_VERTS;
	int nVerts;
	Vertex vertList[];
	int adjMat[][];
	char sortedArray[];
	
	public topo() {
		MAX_VERTS = 20;
		nVerts = 0;
		//初始化这里不能用nVerts,
		//因为nVerts已经赋值为0了,即使后面改变它的值,对于初始化也没有用了
		vertList = new Vertex[MAX_VERTS];
		sortedArray = new char[MAX_VERTS];
		adjMat = new int[MAX_VERTS][MAX_VERTS];
		for(int i=0; i<MAX_VERTS; i++) {
			for(int j=0; j<MAX_VERTS; j++) {
				adjMat[i][j] = 0;
			}
		}
	}
	
	public void addVert(char lab) {
		Vertex v = new Vertex(lab);
		vertList[nVerts++] = v;
	}
	
	public void addEdge(int start, int end) {
		adjMat[start][end] = 1;
	}
	
	public void display(int v) {
		System.out.print(vertList[v].label);
	}
	
	public void topoSort() {
		int orgin_Verts = nVerts;
		while(nVerts > 0) {
			int currentVertex = noSuccessor();
			
			if(currentVertex == -1) {
				System.out.println("The graph is a cirle!");
				return;
			}
			
			sortedArray[nVerts-1] = vertList[currentVertex].label;
			delVertex(currentVertex);
		}
		
		for(int j=0; j<orgin_Verts; j++) {
			System.out.print(sortedArray[j]);
		}
		System.out.println();
	}
	
	public int noSuccessor() {
		boolean isEdge; 

		for(int row=0; row<nVerts; row++) {
			isEdge = false;
			for(int col=0; col<nVerts; col++) {
				if(adjMat[row][col] > 0) {
					isEdge = true;
					break;
				}
			}
            //用标志位判断每一行是否有连接点
			if(isEdge == false) {
				return row;
			}
		}
		
		return -1;
	}
	
	public void delVertex(int delV) {
		if(delV != nVerts-1) {
			//遍历到倒数第二个数就够了,
			//再将最后一个数的下一个数赋值给它并没有什么意义。
			for(int i=delV; i<nVerts-1; i++) {
				vertList[i] = vertList[i+1];
			}
			
			for(int row=delV; row<nVerts-1; row++) {
				rowUp(row, nVerts);
			}
			
			for(int col=delV; col<nVerts-1; col++) {
				//行已经删除完,所以每行的值比原来少一个
				colLeft(col, nVerts);
			}
		}
		nVerts--;
	}
	
	public void rowUp(int row, int length) {
		//需要遍历所有列的数值,向上移
		for(int col=0; col<length; col++) {
			adjMat[row][col] = adjMat[row+1][col];
		}
	}
	
	public void colLeft(int col, int length) {
		for(int row=0; row<length; row++) {
			adjMat[row][col] = adjMat[row][col+1];
		}
	}
	
	public static void main(String[] args) {
		topo gra = new topo();
		
		gra.addVert('A');
		gra.addVert('B');
		gra.addVert('C');
		gra.addVert('D');
		gra.addVert('E');
		gra.addVert('F');
		gra.addVert('G');
		gra.addVert('H');
		
		gra.addEdge(0, 3);
		gra.addEdge(0, 4);
		gra.addEdge(1, 4);
		gra.addEdge(2, 5);
		gra.addEdge(3, 6);	
		gra.addEdge(4, 6);
		gra.addEdge(5, 7);
		gra.addEdge(6, 7);
		
		gra.topoSort();

	}
}











 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值