一篇代码看懂拓扑排序

请直接跑代码

代码

#include <bits/stdc++.h>
using namespace std;
#define MAXVERTEX 15      //最大顶点数,默认为15
typedef struct EdgeNode          //边表
{
    int adjvertex;       //邻接点的下标
    int weight;          //权值
    EdgeNode* next;     //指针指向下一个邻接点
    EdgeNode() {
        next =NULL;
        weight = 0;
        adjvertex = -1;
    }
}*NextNode;

typedef struct VertexNode      //(带有入度)顶点表,可在插入边的时候顺便计算入度
{
    int data;            //顶点信息
    int in;               //顶点入度
    EdgeNode* firstEdge;       //边表指针,指向边表
    VertexNode() {
        in = 0;
        data = 0;
        firstEdge = new EdgeNode;//若初始化为null,则firstEdge->next报错
   }
}AdjList[MAXVERTEX];

typedef struct GraphAdjList
{
    AdjList adjList;             //数组类型的顶点表
    int vertexesNum;        //顶点数
    int edgesNum;           //边数
}*graphAdjList;//在c++中,加上typedef后,graphAdjList表示指针类型的Graph
//否则,只相当于声明了一个graphAdjList变量
//拓扑排序
bool TopologicalSort(graphAdjList GAL)
{
    int i;//用于循环
    int count=0;            //存储要输出的顶点个数
    EdgeNode* e;
    int k;
    //初始化用于辅助的栈
    stack<int> stack;     //栈用于存放入度为0的顶点
    int topNum = 0;            //存储取出的栈顶数
    //将入度为0的顶点放入栈
    for (i = 0; i < GAL->vertexesNum; i++)
    {
        if (GAL->adjList[i].in == 0)
        {
            stack.push(i);
        }
    }
    while (!stack.empty())     //如果存在入度为0的顶点,不断循环
    {
        topNum = stack.top();  //topNum赋值为栈顶指针
        stack.pop();       //栈顶出栈
        count++;          //输出个数自增1
        cout << GAL->adjList[topNum].data << endl;  //输出顶点
        //遍历该顶点的邻接表
        for (e = GAL->adjList[topNum].firstEdge; e; e = e->next)
        {
            k = e->adjvertex;
            if ((--GAL->adjList[k].in) == 0) //邻接点自减1,并判断是否为0
            {
                stack.push(k);
            }
        }
    }
    //循环结束,判断是否是拓扑次序
    if (count < GAL->vertexesNum)
    {
        return false;
    }
    else
    {
        return true;
    }
}
int main() {//从主函数开始阅读是个好习惯
    graphAdjList temp=new GraphAdjList;
    cout << "请输入顶点数:" << endl;
    cin >> temp->vertexesNum;
    cout << "请输入边数:" << endl;
    cin >> temp->edgesNum;
    for (int i = 0; i < temp->edgesNum; i++) {//以a 为前缀的变量均在该函数内声明
        int a_start=0, a_end=0;
        cin >> a_start >> a_end;
        temp->adjList[a_end].in++;
        temp->adjList[a_end].data = a_end;//初始化顶点表
        temp->adjList[a_start].data = a_start;
        //以下为邻接表结点插入方式,可根据需要修改
        NextNode a_pos = temp->adjList[a_start].firstEdge;
        NextNode a_add = new EdgeNode;
        if (a_pos->adjvertex == -1) {//未插入过结点的情况
            a_pos->adjvertex = a_end;
            continue;
        }
        while (a_pos->next) {//a-pos指向边表的最后一个点
            a_pos = a_pos->next;
        }
        a_pos->next = a_add;
        a_add->adjvertex = a_end;
    }
    TopologicalSort(temp);
    return 0;
}

测试数据

拓扑排序样例:
顶点数 :11
边数:13
0 2
1 2
2 3
4 3
1 4
3 5
4 5
3 6
8 6
0 7
7 8
10 0
9 10

标题

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值