无前趋的顶点优先的拓扑排序方法(JAVA)

无前趋的顶点优先的拓扑排序方法

该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:
NonPreFirstTopSort(G){//优先输出无前趋的顶点
while(G中有人度为0的顶点)do{
从G中选择一个人度为0的顶点v且输出之;
从G中删去v及其所有出边;
}
if(输出的顶点数目<|V(G)|)
//若此条件不成立,则表示所有顶点均已输出,排序成功。
Error("G中存在有向环,排序失败!");
}


import java.util.Arrays;   
import java.util.List;
import java.util.ArrayList;
import java.util.Stack;

public class Graph {

int vertexNum; //图的顶点数
ArrayList<ArrayList<Integer>> table; //图的邻接表,table.get(i)存放与i邻接的顶点
Stack<Integer> stack; //存放入度为0的顶点
int[] result; //拓朴排序的结果
int[] in;// 入度,in[i]表示顶点i的入度

/**
*
* 构造一个图
*
* @param num
* 图的顶点数
*
*/
public Graph(int num) {

vertexNum = num;
table = new ArrayList<ArrayList<Integer>> (vertexNum);
for(int i=0;i<vertexNum;i++)
table.add(new ArrayList<Integer>());
stack = new Stack<Integer>();
result = new int[vertexNum];
in = new int[vertexNum];

}

/**
* 向图中添加无向边
*
* @param I
* 边的一个顶点
* @param J
* 边的另一个顶点
* @return 是否添加成功
*/
public boolean addEdge(int I, int J) {

/**
* 判断用户输入的是否是一个顶点,如果是,则返回flase,添加不成功
*/
if (J == I) {
return false;
}

/**
* 判断所输入的顶点值是否在图所顶点范围值内,如果不在,则提示顶点不存在
*
*/
if (I < vertexNum && J < vertexNum && I >= 0 && J >= 0) {
/**
*
* 判断边是否存在
*/

if (isEdgeExists(I, J)) {
return false;
}

/**
* 添加边,将孤头的入度加1
*/

table.get(I).add(J);
in[J]++;
return true;
}
return false;
}

/**
* 判断有向边是否存在
*
* @param i
* 要查询的有向边的一个孤尾
* @param j
* 要查询的有向边的另一个孤头
* @return 边是否存在,false:不存在,true:存在
*/

public boolean isEdgeExists(int i, int j) {

/**
* 判断所输入的顶点值是否在图所顶点范围值内,如果不在,则提示顶点不存在
*
*/
if (i < vertexNum && j < vertexNum && i >= 0 && j >= 0) {

if (i == j) {
return false;
}

/**
* 判断i的邻接结点集是否为空
*/

if (table.get(i) == null) {
return false;
}

/**
* 判断这条边是否存在,如果存在,则提示边已经存在
*/
for (int q = 0; q < table.get(i).size(); q++) {

if (((Integer) table.get(i).get(q)).intValue() == j) {
System.out.println("顶点" +i+"和"+"顶点"+j+ "这两点之间存在边");
return true;
}
}
}
return false;
}

public void TopSort() { //无前趋的顶点优先的拓扑排序方法

for (int i = 0; i < vertexNum; i++) //无前趋的顶点入栈
if (in[i] == 0)
stack.push(i);
int k = 0;
while (!stack.isEmpty()) {

result[k] = (Integer) stack.pop(); //弹出一个无前趋的顶点,并放入拓扑排序的结果集

if (table.get(result[k]) != null) { //这个顶点的邻接表非空
for (int j = 0; j < table.get(result[k]).size(); j++) {

int temp = (Integer) table.get(result[k]).get(j);
//对result[k]每一个邻接点进行入度减1操作
if (--in[temp] == 0) { //如果temp的入度为0,进栈.
stack.push(temp);
}
}
}
k++;
}

if (k < vertexNum) {
System.out.println("有回路");
System.exit(0);
}
}

public int[] getResult() {
return result;
}

}

测试:
[img]http://dl.iteye.com/upload/attachment/0075/7672/adfae43b-d8eb-3a91-b8de-9f04e59bd7e0.gif[/img]

import java.util.List;   

public class GraphTest {

public static void main(String args[]){
Graph graph = new Graph(6);
graph.addEdge(1, 0);
graph.addEdge(2, 0);
graph.addEdge(3, 0);
graph.addEdge(1, 3);
graph.addEdge(2, 3);
graph.addEdge(3, 5);
graph.addEdge(4, 2);
graph.addEdge(4, 3);
graph.addEdge(4, 5);

graph.TopSort();
int[] list = graph.getResult();
System.out.println("拓扑排序的结果为:");
for(int i : list){
System.out.print(i+" ");
}
}

}


运行:
C:\>java GraphTest
拓扑排序的结果为:
4 2 1 3 5 0

下载源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值