宣告:圖片及內容基於:https://www.bilibili.com/video/BV1Wp4y1X79x?from=articleDetail
原理
AOV網
拓撲排序
資料結構
核心程式碼
void ALGraph::TopologicalSort(){ for(int i=0;i<vertexNum;i++){ //in為0則壓棧 if(adjList[i].in==0){ s.push(adjList[i]); } } while(!s.empty()){ //迴圈終止條件:棧為空 vertexNode v=s.top(); //彈棧輸出 s.pop(); cout<<v.vertex<<" "; count++; //計數加一 ArcNode *a=v.firstEdge; while(a){ //對彈出的結點遍歷,所有遍歷過的結點的in-1 adjList[a->adjvex].in--; int tmp=adjList[a->adjvex].in; if(tmp==0){ //如果某結點的in變為0,則將其壓棧 s.push(adjList[a->adjvex]) ; } a=a->next; } } if(count<vertexNum) cout<<"有環"<<endl; //如果計數小於頂點數則說明有環 else cout<<"無環,成功完成"<<endl; }
完整程式碼
#include<iostream>
#include<stack>
#include<cstring>
#define MAX 100
using namespace std;
typedef struct ArcNode{ //邊結點
int adjvex; //頂點下標
ArcNode *next;
}ArcNode;
typedef struct{
int in; //in是入度
string vertex; //頂點資訊
ArcNode *firstEdge;
}vertexNode,VertexNode[MAX];
class ALGraph{
private:
int vertexNum,arcNum; //頂點數,邊數
VertexNode adjList; //頂點陣列
stack<vertexNode> s; //棧
int count=0; //計數
public:
ALGraph(string v[],int n,int e);
void display(); //列印鄰接表
void TopologicalSort(); //拓撲排序
};
void ALGraph::TopologicalSort(){
for(int i=0;i<vertexNum;i++){ //in為0則壓棧
if(adjList[i].in==0){
s.push(adjList[i]);
}
}
while(!s.empty()){ //迴圈終止條件:棧為空
vertexNode v=s.top(); //彈棧輸出
s.pop();
cout<<v.vertex<<" ";
count++; //計數加一
ArcNode *a=v.firstEdge;
while(a){ //對彈出的結點遍歷,所有遍歷過的結點的in-1
adjList[a->adjvex].in--;
int tmp=adjList[a->adjvex].in;
if(tmp==0){ //如果某結點的in變為0,則將其壓棧
s.push(adjList[a->adjvex]) ;
}
a=a->next;
}
}
if(count<vertexNum) cout<<"有環"<<endl; //如果計數小於頂點數則說明有環
else cout<<"無環,成功完成"<<endl;
}
ALGraph::ALGraph(string v[],int n,int e){ //建構函式
vertexNum=n;
arcNum=e;
for(int i=0;i<vertexNum;i++){ //頂點初始化
adjList[i].in=0;
adjList[i].vertex=v[i];
adjList[i].firstEdge=NULL;
}
ArcNode *s;
int vi,vj;
for(int i=0;i<arcNum;i++){
s=new ArcNode;
cout<<"請輸入邊的兩個端點:"<<endl;
cin>>vi>>vj;
s->adjvex=vj;
s->next=adjList[vi].firstEdge; //頭插法
adjList[vi].firstEdge=s;
adjList[vj].in++; //入度加一
}
}
void ALGraph::display(){
for(int i=0;i<vertexNum;i++){
ArcNode *p=adjList[i].firstEdge;
cout<<adjList[i].in<<" ";
cout<<adjList[i].vertex;
if(p) cout<<"->";
while(p){
cout<<p->adjvex<<" ";
p=p->next;
if(p) cout<<"->";
}
cout<<endl;
}
}
int main(){
int n,e;
cout<<"請輸入頂點數和邊數"<<endl;
cin>>n>>e;
cout<<"請輸入結點資訊"<<endl;
string v[MAX];
for(int i=0;i<n;i++){
cin>>v[i];
}
ALGraph algraph(v,n,e);
algraph.display();
algraph.TopologicalSort();
return 0;
}
輸入:
7 10
C1 C2 C3 C4 C5 C6 C7
0 2
0 3
1 3
1 5
2 4
3 4
3 6
3 5
4 6
5 6
輸出:
0 C1->3 ->2
0 C2->5 ->3
1 C3->4
2 C4->5 ->6 ->4
2 C5->6
2 C6->6
3 C7
C2 C1 C3 C4 C5 C6 C7 無環,成功完成(注意拓撲排序答案可能不唯一)