利用拓扑序列判断图中是否有环原理

本文通过C语言实现,介绍如何利用拓扑序列来判断有向无权图中是否存在环。通过邻接表存储图,计算每个节点的入度,并在寻找拓扑序列的过程中检查是否存在无法减为0的入度节点,以此来确定图中是否存在环。如果拓扑序列包含了所有节点,说明图中无环;反之,存在环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include"stdio.h"//有向无权图
#include"stdlib.h"//采用邻接表存储图
structlinjienode//拓扑序列
{                              //利用拓扑序列判断图中是否有环原理:
    intlocation;              //如果图中存在环,因为在寻找拓扑序列时,
    structlinjienode * next;  //入度的减少永远都无法破坏到该环
};                             //也就是该环中的所有点的入度都不可能
structnode                    //减为0,即:环中的所有点都不可能进入
{                              //拓扑序列中;使拓扑序列中的点永远都无法
    intindu;                  //包含图中的所有点
    structlinjienode * firstlinjie;
};
int main()
{
    inta,i,j,k,nodeshu,bianshu,node1,node2,sum,sign,t;
    structlinjienode * temp;
    scanf("%d",&a);
    for(i=0;i<a;i++)
    {
        sum=0;
        scanf("%d %d",&nodeshu,&bianshu);
        structnode nodezu[nodeshu];
        for(j=0;j<nodeshu;j++)
        {
            nodezu[j].indu=0;
            nodezu[j].firstlinjie=NULL;
        }
        for(j=0;j<bianshu;j++)
        {
            scanf("%d %d",&node1,&node2);
            nodezu[node2-1].indu++;//对应点的入度也要自加
            temp=(structlinjienode *)malloc(sizeof(structlinjienode));
            temp->location=node2-1;
            temp->next=NULL;
            temp->next=nodezu[node1-1].firstlinjie;
            nodezu[node1-1].firstlinjie=temp;
        }
        while(1)
        {
            sign=0;
            for(j=0;j<nodeshu;j++)
            {
                if(nodezu[j].indu==0)
                {
                    sign=1;//如果找到了就做个标记
                    sum++;//sum记录我们加入到拓扑序列中点的总数
                    nodezu[j].indu--;
                    for(temp=nodezu[j].firstlinjie;temp!=NULL;temp=temp->next)
                    {//把该点指向的所有点的入度数都减一
                        t=temp->location;
                        nodezu[t].indu--;
                    }
                }
                if(sign==1)
                {//我们每次都从头开始到尾找一个入度为0的点
                    break;
                }
            }
            if(sign==0)
            {//如果所有点都遍历了,但还是没找到入度为0的点就退出while循环,不找了
                break;
            }
        }
        if(sum==nodeshu)//判断是否拓扑序列是否包含了图中所有点
        {//如果包含了所有点,则说明改图不存在环,若没包含所有点则一定存在环
            printf("Not A Loop Graph.\n");
        }
        else
        {
            printf("A Loop Graph.\n");
        }
    }
    return0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值