Java實現AOV圖的拓撲排序
拓撲排序作為圖的應用,了解拓撲排序必須首先了解AOV圖。
AOV網表示一個有向圖中頂點,用弧表示頂點之間的優先關系。如下圖所示,在AOV網中,若從頂點vi到頂點vj之間存在一條有向路徑,則稱頂點vi為頂點vj的前驅,頂點vj為頂點vi的后繼。注意,AOV圖不能有回路,否則會將序列陷入死循環,稱為死鎖。
進行拓撲排序,一般步驟如下:
<1>在AOV網中選擇一個入度為0的頂點
<2>在AOV網中刪除此頂點及其相連的有向邊
<3>重復步驟<1>和<2>,直到AOV網中沒有入度為0的頂點為止
由于拓撲排序具有不確定性,因此經過排序的序列應人而異,不過大多序列的邏輯關系能夠走通。
程序如下:
package 拓撲排序;
/*
* 在AOV網中尋找拓撲排序序列的步驟如下:
* <1>在AOV網中選擇一個入度為0的頂點
* <2>從AOV往中刪除此頂點以及與其相連的有向邊
* <3>重復步驟<1>和<2>。直到AOV網中沒有入度為0的頂點
*/
public class TopoSort {
/**
* @author 劉雁冰
* @date 2015-02-14 20:22
*/
/*
* Max:定義頂點的最大容量為100
* ver:使用內部Vertexs類創建一個數組ver,存儲頂點的關鍵字
* map:AOV網的鄰接矩陣表
* n:頂點的數量
* topoSort:存儲最終得到的序列
*/
static int Max=100;
static Vertexs ver[];
static int map[][];
static int n;
static char topoSort[];
public static void main(String[] args) {
// TODO Auto-generated method stub
ver=new Vertexs[Max];
map=new int[Max][Max];
n=0;
topoSort=new char[Max];
//初始化鄰接矩陣
for(int i=0;i<Max;i++){
for(int j=0;j<Max;j++){
map[i][j]=0;
}
}
TopoSort ts=new TopoSort();
//讀入AOV網頂點的關鍵字
ts.addVertex('A');
ts.addVertex('B');
ts.addVertex('C');
ts.addVertex('D');
ts.addVertex('E');
ts.addVertex('F');
ts.addVertex('G');
ts.addVertex('H');
ts.addVertex('I');
ts.addVertex('J');
ts.addVertex('K');
ts.addVertex('L');
//讀入AOV網邊的連接信息,由于是有向圖,只需讀入一次
ts.addEdge(0, 1);
ts.addEdge(0, 3);
ts.addEdge(0, 10);
ts.addEdge(1, 10);
ts.addEdge(2, 3);
ts.addEdge(2, 4);
ts.addEdge(2, 5);
ts.addEdge(3, 7);
ts.addEdge(5, 7);
ts.addEdge(5, 6);
ts.addEdge(5, 8);
ts.addEdge(6, 8);
ts.addEdge(6, 9);
ts.addEdge(10, 11);
ts.addEdge(11, 9);
ts.addEdge(11, 6);
ts.topoSort();
}
//構造頂點關鍵字數組
public void addVertex(char v){
ver[n++]=new Vertexs(v);
}
//構造邊的鄰接矩陣
public void addEdge(int start,int end){
map[start][end]=1;
}
public void topoSort(){
//num:頂點數量n要進行遞減,因此起始存入num,作為輸出序列遍歷使用
//isEdge:判定該邊是否相連
int num=n;
boolean isEdge;
while(n>0){
//選取一個入度為0的頂點
int currVer=0;
//遍歷鄰接矩陣
for(int row=0;row<n;row++){
isEdge=false;
for(int col=0;col<n;col++){
if(map[row][col]>0)
isEdge=true;
}
//抽取鄰接邊表中沒有出度的頂點(將鄰接表行數賦值給當前頂點)
if(!isEdge)
currVer=row;
}
//將沒有出度的頂點存入序列結果最后的位置
topoSort[n-1]=ver[currVer].value;
/*
* 刪除頂點操作
* 當前頂點不為最后頂點時進行
*/
if(currVer!=n-1){
//頂點關鍵字數組往后移動一位
for(int i=currVer;i<n;i++)
ver[i]=ver[i+1];
/*
* 移動鄰接表行列,覆蓋原值
*/
//鄰接表行數往后移動一位(向右移動)
for(int row=currVer;row<n-1;row++)
for(int col=0;col<n;col++)
map[row][col]=map[row+1][col];
//鄰接表列數往后移動一位(向左移動)
for(int col=currVer;col<n-1;col++)
for(int row=0;row<n;row++)
map[row][col]=map[row][col+1];
}
n--; //下一個頂點
}
//輸出結果
System.out.println("該圖的拓撲排序序列為:");
for(int i=0;i<num;i++){
}
}
}
class Vertexs{
public char value;
public Vertexs(char v){
value=v;
}
}
測試結果如下:
本文由用戶 c6g3 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!