数据结构之拓扑排序

本文介绍了一种使用邻接表表示有向图的方法,并实现了拓扑排序算法。通过具体的代码实例,详细展示了如何创建邻接表以及如何利用拓扑排序找出图中的一个可能的线性序列。

感觉重点就是邻接表的创建和tp(topoSort()函数中的一个变量)的变化很奇妙,相当于是一个静态指针的用法。


#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a));
#define For(a,b) for(int i = a;i<b;i++)
#define LL long long
#define MAX_N 100010
#define VN 10
using namespace std;
struct EdgeNode;
typedef struct EdgeNode *PEdgeNode;
typedef struct EdgeNode *EdgeList;
typedef int Elemtype;
typedef int Adjtype;
typedef int Vextype;
//存边表中结点的信息以及下一结点的指针
struct EdgeNode
{
    Elemtype endvex;
    Adjtype weight;
    PEdgeNode nextedge;
};
//存放边表头结点信息
typedef struct
{
    Vextype vertex;
    EdgeList edgelist;
}Vexnode;
//代表图中结点的集合
typedef struct
{
    Vexnode vex[VN];
}GraphList;
//临时存放边的起始点和终点的结构体
struct Edge_p
{
    int start;
    int stop;
}w[20];
//为得到各邻接表表头的入度
void find_Indegree(GraphList *gralist,Elemtype *indegree,Elemtype node_num)
{
    EdgeList p;
    for(int i = 0; i<node_num; i++)
        indegree[i] = 0;
    for(int i = 0; i<node_num; i++)
    {
        p = gralist->vex[i].edgelist;
        while(p)
        {
            ++indegree[p->endvex];
            p = p->nextedge;
        }
    }
}
//得到拓扑序的过程
int Get_topoSort(GraphList *gralist,int *indegree,int *topo,int tp,int node_num)
{
    EdgeList p;
    int toponum = 0,flag = 0,w = 0;
    while(tp != -1)
    {
        flag = tp;
        tp = indegree[tp];
        topo[toponum++] = flag;
        for(p = gralist->vex[flag].edgelist; p != nullptr; p = p->nextedge)
        {
            w = p->endvex;
            if(--indegree[w] == 0)
            {
                indegree[w] = tp;
                tp = w;
            }
        }
    }
    return toponum;
}
//拓扑排序过程调用的主函数
int topoSort(GraphList *gralist,Elemtype *topo,Elemtype node_num)
{
    int indegree[VN];
    int tp = -1;
    find_Indegree(gralist,indegree,node_num);
    for(int i = 0; i<node_num; i++)
    {
        if(indegree[i] == 0)
        {
            indegree[i] = tp;
            tp = i;
        }
    }
    int topo_num = 0;
    topo_num = Get_topoSort(gralist,indegree,topo,tp,node_num);
    if(topo_num < node_num) return 0;
    return 1;

}
int main()
{
    GraphList gralist;
    int topo[VN];
    int edge_num = 11,node_num = 9;
    int start = 0,stop = 0;
    for(int i = 0; i<edge_num; i++)
    {
        cin>>start>>stop;
        w[i].start = start;
        w[i].stop = stop;
    }
    cout<<endl<<endl;
    for(int i = 0; i<node_num; i++)
    {
        gralist.vex[i].vertex = i;
        gralist.vex[i].edgelist = nullptr;
    }
    int cur = 0;
    PEdgeNode p;
    int flag = w[0].start;
    for(int i = 0; i<node_num; i++)
    {
        while(flag == i)
        {
            p = (PEdgeNode)malloc(sizeof(EdgeNode));
            p->nextedge = gralist.vex[i].edgelist;
            p->endvex = w[cur].stop;
            gralist.vex[i].edgelist = p;
            cur++;
            flag = w[cur].start;
        }
    }
    cout<<"邻接表表示如下:"<<endl<<endl;
    for(int i = 0; i<node_num; i++)
    {
        EdgeList q;
        q = gralist.vex[i].edgelist;
        cout<<gralist.vex[i].vertex<<" ";
        while(q != nullptr)
        {
            cout<<q->endvex<<' ';
            q = q->nextedge;
        }
        cout<<endl;
    }
    topoSort(&gralist,topo,node_num);
    
    cout<<"以下是拓扑序的一种表示形式:"<<endl<<endl;
    
    for(int i = 0; i<node_num; i++)
    {
        cout<<topo[i]<<' ';
    }
    cout<<endl;
    return 0;
}
/*

2016.10.09

For exmple:

0 2
0 7
1 2
1 3
1 4
2 3
3 5
3 6
4 5
7 8
8 6


*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值