声明:图片及内容基于:https://www.bilibili.com/video/BV1Wp4y1X79x?from=articleDetail

原理

AOV网

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

拓扑排序

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

数据结构

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

核心代码

AOV网与拓扑排序-LMLPHP

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 无环,成功完成(注意拓扑排序答案可能不唯一)

AOV网与拓扑排序-LMLPHP

AOV网与拓扑排序-LMLPHP

04-05 13:48