基于邻接表存储的图的拓扑排序算法

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
using namespace std;
#define MAXNODE 1000// 图中顶点的最大个数
typedef int infotype;
typedef int vertype;
struct ArcNode//边节点类型
{
    int adjvex;//该边的终点编号
    ArcNode *next;//指向下一条边的指针
    infotype *info;//该边的相关信息
};
struct VerNode//表头结点
{
    vertype vertex;// 顶点信息
    ArcNode *firstarc;// 指向第一个邻接点的指针
};
struct AlGraph//邻接表
{
    VerNode vertices[MAXNODE];//邻接表
    int vexnum,arcnum;// 顶点和边的数目
};
AlGraph CreatAdjList(AlGraph g)//建立有向图的邻接表存储结构
{
    int n;
    cout<<"输入顶点个数:"<<endl;
    cin>>n;
    cout<<"输入顶点的名称:"<<endl;
    for(int i=1;i<=n;i++)
    {
        cin>>g.vertices[i].vertex;//输入顶点信息
        g.vertices[i].firstarc=NULL;//初始化每个链表为空
    }
    int v1,v2;
    cout<<"输入图的边,两个顶点之一为0,表示输入结束。"<<endl;
    cin>>v1>>v2;//输入一条边依附的两个顶点序号
    int e=0;//图的边数
    while(v1!=0&&v2!=0)//题目要求两顶点之一为0表示结束
    {
        //i=GraphLocateVertex(g,v1);
        //j=GraphLocateVertex(g,v2);
        ArcNode *p= (ArcNode*)malloc(sizeof(ArcNode));
        //用头插法插入结点以建立链表
        p->adjvex=v2;
        p->next=g.vertices[v1].firstarc;
        g.vertices[v1].firstarc=p;
        e++;
        cin>>v1>>v2;
    }
    g.vexnum=n;
    g.arcnum=e;
    return g;
}
void CountInDegree(AlGraph g,int *indegree)//取得图中各个顶点的入度
{
    for(int i=1;i<=g.vexnum;i++)
    {
        indegree[i]=0;
        for(int j=1;j<=g.vexnum;j++)//遍历图
        {
            ArcNode * p = g.vertices[j].firstarc;
            for(;p!=NULL;p=p->next)
            {
                int k = p->adjvex;
                if(g.vertices[k].vertex==g.vertices[i].vertex)indegree[i]++;
            }
        }
        //cout<<indegree[i]<<endl;
    }
}
void TopologicalSort(AlGraph g)//拓扑排序算法
{
    int indegree[MAXNODE];//保存各个顶点的入度信息
    CountInDegree(g,indegree);//对各顶点求入度
    stack<vertype> s;
    for(int i=1;i<=g.vexnum;i++)
        if(!indegree[i])s.push(g.vertices[i].vertex);//入度为0者进栈
    int count=0;
    while(!s.empty())
    {
        vertype v = s.top();
        s.pop();
        cout<<v<<" ";//输出顶点
        count++;
        for(ArcNode *p = g.vertices[v].firstarc;p!=NULL;p=p->next)
        {
            //对i号顶点的每个邻接点的入度减1,新产生的入度为0的顶点进栈
            int k = p->adjvex;
            if(!(--indegree[g.vertices[k].vertex]))s.push(g.vertices[k].vertex);
        }
    }
    if(count<g.vexnum)cout<<"图中存在回路"<<endl;
    else cout<<"存在拓扑序列"<<endl;
}
int main()
{
    AlGraph g;
    g=CreatAdjList(g);
    cout<<"图建立成功."<<endl;
    TopologicalSort(g);
    return 0;
}

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/a946665026/article/details/9112271
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞