关于topsort

 拓扑排序

定义:对一个有向无环图(Directed Acyclic Graph简称DAG) G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

通俗的说就是根据给出的部分排序信息得到全部顺序的操作。

注意:当有向图中存在有向环时,拓扑序列不存在,即不能对该图进行拓扑排序。

例如:

1>2 1>3 1>4 3>2 3>5 4>5 6>4 6>5

如图

我们发现6和1没有前驱,所以我们随机选一个输出(拓扑排序结果不唯一;也可利用队列或数组存储,在main函数中输出),我们先输出6,删除和6有关的边,得到如下结果: 


我们发现1是没有前驱的,所以我们输出1(或存储),删除和1有关的边,得到如下图结果: 


继续判断前驱为0的点,输出并删除与它有关的边,选择删除4(可存储;也可选择3),结果如下。 


输出没有前驱的3(或者存储)并删除相关的边,结果如下图。


2和5 选择任意一个输出(或存储),拓扑排序完成。

一些拓扑排序基础题:

来呀,点我~

我也很简单,23333~

无前趋的顶点优先的拓扑排序方法  

 该方法的每一步总是输出当前无前趋(即入度为零)的顶点;利用数组模拟:

#include<stdio.h>//模拟队列
#include<string.h>
int n,m,w;
int s[120],book[120][120],line[120];
void topsort()
{
    int k;
    for(int j=0;j<n;j++)
    {
        for(int i=1;i<=n;i++)
        {
         if(s[i]==0)//入度为0
         {
             k=i;
             break;
         }
        }
        line[w++]=k;//进数组
        s[k]=-1;
        for(int i=1;i<=n;i++)
        {
            if(book[k][i]==1)
                s[i]--;
        }
    }
}
int main()
{
        scanf("%d%d",&n,&m);
        int a,b;w=0;
        memset(book,0,sizeof(book));
        memset(s,0,sizeof(s));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            if(book[a][b]==0)
            {
               book[a][b]=1;
               s[b]++;//入度加1
            }
        }
        topsort();
        printf("%d",line[0]);
        for(int i=1;i<w;i++)
        {
           printf(" %d",line[i]);
        }
    return 0;
}

以上是利用数组模拟队列进行正序输出;

接下来是拓展:

无后继的顶点优先拓扑排序方法  

     该方法的每一步均是输出当前无后继(即出度为0)的顶点。对于一个DAG,按此方法输出的序列是逆拓扑次序

仍然可以利用数组模拟的方法存放之后逆序输出;也可以用栈来存放,排序方法如上,入栈之后按顺序输出即可。

我是利用广搜和深搜实现拓扑排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值