关于图的拓扑排序

实现下图的拓扑排序。

 

                 

设计思想:

首先对有向图,我们采取邻接表作为数据结构。且将表头指针改为头结点,

其数据域存放该结点的入度,入度设为零的结点即没有前趋。

 

在建立邻接表输入之前,表头向量的每个结点的初始状态为数据域VEX(入度)为零,指针域NXET为空,每输入一条弧< J, K > 建立链表的一个结点,同时令k 的入度加1,因此在输入结束时,表头的两个域分别表示顶点的入度和指向链表的第一个结点指针。

 

在拓扑排序的过程之中,输入入度为零(即没有前趋)的顶点,同时将该顶点的直接后继的入度减1。

(1)、查邻接表中入度为零的顶点,并进栈。

(2)、当栈为空时,进行拓扑排序。

(a)、退栈,输出栈顶元素V。

(b)、在邻接表中查找Vj的直接后继Vk,将Vk的入度减一,并令入度减至零的顶点进栈。

(3)、若栈空时输出的顶点数不是N个则说明有向回路,否则拓扑排序结束。为建立存放入度为零的顶点的栈,不需要另分配存储单元,即可借入入度为零的数据域。一方面,入度为零的顶点序号即为表头结点的序号,另一方面,借用入度为零的数据域存放带链栈的指针域(下一个入度的顶点号)。

算法设计:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
#define MAX 9999
stack<int>mystack;
int indegree[MAX];
struct node 
{
    int adjvex;
    node* next;
}adj[MAX];

int Create(node adj[],int n,int m)//邻接表建表函数,n代表定点数,m代表边数
{
    int i;
    node *p;
    for(i=0;i<=n-1;i++)
    {
        adj[i].adjvex=i;
        adj[i].next=NULL;
    }
    for(i=0;i<=m-1;i++)
    {
        cout<<"请输入第"<<i<<"条边:";
        int u,v;
        cin>>u>>v;
        p=new node;
        p->adjvex=v;
        p->next=adj[u].next;
        adj[u].next=p;
    }
    return 1;
}

void print(int n)//邻接表打印函数
{
    int i;
    node *p;
    for(i=0;i<=n-1;i++)
    {
        p=&adj[i];
        while(p!=NULL)
        {
            cout<<p->adjvex<<' ';
            p=p->next;
        }
        cout<<endl;
    }
}

void topsort(node adj[],int n)
{
    int i;
    node *p;
    memset(indegree,0,sizeof(indegree));
    for(i=0;i<=n-1;i++)
    {
        p=adj[i].next;
        while(p!=NULL)
        {
            indegree[p->adjvex]++;
            p=p->next;
        }
    }
    for(i=0;i<=n-1;i++)
    {
        if(indegree[i]==0)
            mystack.push(i);
    }
    int count=0;
    while(mystack.size()!=0)
    {
        i=mystack.top();
        mystack.pop();
        cout<<i<<' ';
        count++;
        for(p=adj[i].next;p!=NULL;p=p->next)
        {
            int k=p->adjvex;
            indegree[k]--;
            if(indegree[k]==0)
                mystack.push(k);
        }
    }
    cout<<endl;
    if(count<n)cout<<"有回路"<<endl;
}



int main()
{
    int n;
    int m;
    cout<<"请输入顶点数及边数:";
    cin>>n>>m;
    Create(adj,n,m);
    cout<<"输入的邻接表为:"<<endl;
    print(n);
    cout<<"拓扑排序结果为:"<<endl;
    topsort(adj,n);
    system("pause");
    return 0;
}

运行结果:

原创文章 10 获赞 10 访问量 401

猜你喜欢

转载自blog.csdn.net/weixin_41553587/article/details/105842638