//圖的鄰接表不是唯一的,因爲在每個頂點的鄰接表中,各邊結點的鏈接次序可以任意安排,
//其具體鏈接次序與邊的輸入次序和生成算法有關。
//下面給出建立圖的鄰接表的有關類型定義和生成一個有向圖鄰接表的算法描述
typedef int VertexType;//這裏有分號 #define纔沒有分號
const int MaxVertexNum=20;//{圖的最大頂點數,它應不小於具體圖的頂點數n};
const int MaxEdgeNum=30;//{圖的最大邊數,它應不小於具體圖的最大邊數e};
typedef VertexType vexlist[MaxVertexNum];//定義vexlist爲存儲頂點信息的數組類型
struct edgenode//定義鄰接表中的邊結點類型
{
int adjvex;//鄰接點域
int weight;//權值域,對無權圖可省去
edgenode *next;//指向下一個邊結點的鏈域
};//邊忘了這個分號
typedef edgenode *adjlist[MaxVertexNum];//這義adjlist爲存儲n個表頭指針的數組類型
void Create2(vexlist GV,adjlist GL,int n,int e) //看看GL到底是什麼: GL[i]->adjvex
//通過從鍵盤上輸入的n個頂點信息和e條有向邊的信息
//建立頂點數組GV和鄰接表GL
{
int i,j,k,w;
//建立頂點數組
cout<<"輸入"<<n<<"個頂點"<<endl;
for(i=0;i<n;i++)
cin>>GV[i];
//初始化鄰接表,即將表頭向量中的每個域置空
for(i=0;i<n;i++)
GL[i]=NULL;
//建立鄰接表
cout<<"輸入"<<e<<"條邊"<<endl;
for(k=1;k<=e;k++)
{
//輸入一條邊<i,j>
cin>>i>>j;//>>w;
//由系統分配一個新結點
edgenode *p=new edgenode;
//將j的值賦給新結點的鄰接點域
p->adjvex=j;
//p->weight=w;
//將新結點插入到vi鄰接表的表頭
p->next=GL[i];
GL[i]=p;
}
}
void Toposort(adjlist GL,int n)//此算法的時間複雜度爲o(n+e) //n爲頂點數,e爲邊數
//利用鄰接表GL表示的有向圖進行拓樸排序
{
int i,j,k,top,m=0;//m用來統計拓樸序列中的頂點
//top的值爲一個入度爲0的頂點序號,top指向的值爲下一個入度爲0的頂點序號
edgenode *p;
//定義存儲圖中每個頂點入度的一維整型數組d
int *d=new int[n];
//初始化數組d中的每個元素值爲0
for(i=0;i<n;i++)
d[i]=0;
//利用數組d中的對應元素統計出每個頂點的入度
for(i=0;i<n;i++)
{
p=GL[i];
while(p!=NULL)
{
j=p->adjvex;
d[j]++;
p=p->next;
}
}
//初始化用於鏈接入度爲0的元素的棧的棧頂指針top爲-1
top=-1;
//建立初始化棧
for(i=0;i<n;i++)
if(d[i]==0)
{
d[i]=top;
top=i;
}
//每循環一次刪除一個頂點及所有出邊
cout<<"拓樸序列如下:"<<endl;
while(top!=-1)
{
j=top;//j的值爲一個入度爲0的頂點序號
top=d[top];//刪除棧頂點元素
cout<<j<<" ";//輸出一個頂點
m++;//輸出的頂點個數加1
p=GL[j];//p指向vj鄰接點表的第一個結點
while(p!=NULL)
{
k=p->adjvex;//vk是vj的一個鄰接點
d[k]--;//vk的入度減1
if(d[k]==0)//把入度爲0的元素進棧
{
d[k]=top;
top=k;
}
p=p->next;//p指向vj鄰接點表的下一個結點
}
}
cout<<endl;
if(m<n)//當輸出的頂點數小於圖中的頂點數時,輸出有迴路信息(拓樸圖是無迴路的,因
//爲若帶有迴路,則迴路上的所有活動都無法進行)
{
cout<<"The network has a cycle!"<<endl;
}
}
void main()
{
vexlist GV;
adjlist GL;
int n=6;
int e=8;
Create2(GV,GL,n,e);
//cout<<GL[0]->adjvex;
Toposort(GL,n);
}
//測試用例如下:
/*
輸入6個頂點
0 1 2 3 4 5
輸入8條邊
0 2
1 2
1 3
1 4
2 3
3 5
4 5
2 5
拓樸序列如下:
1 4 0 2 3 5
*/
/*
http://java2.xinwen365.net
QQ羣:
34409541 討論網頁
34409326 討論JAVA 已滿
34408784 討論VC++
34409699 討論VC++
9143041 討論MFC編程
10614204 討論C#
10613030 討論Win32編程
10613067 討論遊戲開發
18779860 討論JAVA
*/