拓扑排序dfs实现

拓扑排序

  1. 用来验证图中是否有环。
  2. 用来进行确定前驱关系。
    比如a < b , c < d, c < b 可以确定
    a < c < b < d
    或者
    c < a < b < d
    如果没有环的话一定可以存在一条这样的链,但是如果有环就不能进行拓扑排序。这个例子就是不能 a > b 且 b > a;

算法思想

使用dfs 进行进行确定拓扑顺序,就是对每一条路径进行遍历,如果这条路径中的某个父节点被二次访问就有环,否则就没有环。

伪代码

//判断是否有环(true 没有; false 有)
bool dfs(u) {
	一次访问节点。
	for(遍历以u为入弧的定点){
			if(二次访问了父亲节点)return false;	//亮点
			else if(如果没访问过的子节点) {		 //经典dfs
				if(子节点有环)return false;
			}
		}
		//表示这个节点的到底都没有环
		确定这个节点以及子节点都没环。
		倒着将沿途的节点加入拓扑队列    //因为这是递归的返回,就是到头回来的过程
		return true;
	}
bool topoSort(){
	for(遍历节点){
		if(没访问过){
			if(下一个节点有环) return false;
		}
	}
	//所有节点都没环
	return true;
}

两句if 可以合成为 
if(没访问过 && 有环)return false;

代码


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 100;
int c[maxn];
int topo[maxn], t, n;
int G[maxn][maxn];


bool dfs(int u)
{
	c[u] = -1;
	for(int v = 0; v < n; v++)
	{
		if(G[u][v])
		{
			if(c[v] < 0)
				return false;
			else if(!c[v] && !dfs(v))
                return false;
		}
	}
	c[u] = 1;
	topo[--t] = u;
	return true;
}
bool topoSort()
{
	t = n;
	memset(c,0,sizeof(c));
	for(int u = 0; u < n; u++){
		if(!c[u] && !dfs(u))
            return false;
	}
	return true;
}


int main()
{
    char ch[100] = {'a', 'b', 'c', 'd'};
    n = 4;
    G[0][1] = 1;
    //G[1][0] = 1;
    G[2][1] = 1;
    G[3][2] = 1;
    if(!topoSort()){
        printf("无法拓扑排序\n");
        return 0;
    }
    for(int i = 0; i < 4; i++){
        printf("%c ", ch[topo[i]]);
    }
    printf("\n");
}

这个代码最精彩的部分就是使用c[u] = -1判断本趟结果是否有环。
区别于经典的dfs标志数组用了两个值表示不同的意思。
c[u] = 0:表示没访问
c[u] = 1:表示u已经被访问了,且以u及其子节点不含环。
c[u] = -1 : 表示以u顶点的节点已经被访问了,且是父节点。

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值