AOV網與拓撲排序

gonghr發表於2021-04-05

宣告:圖片及內容基於: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 無環,成功完成(注意拓撲排序答案可能不唯一)

相關文章