22.4-5拓扑排序BFS

本文介绍了一种使用队列实现的拓扑排序算法,通过不断移除入度为0的节点并更新相邻节点的入度来完成排序过程。该算法适用于有向无环图(DAG)的场景。

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

  • 这个问题和宽度优先搜索很相似,是横向扩展入度为0的节点
  • 队列中都是入度为0的元素,将一个元素出队列之前,将与他相连的元素的入度减1,如果为0将新元素入队列
#include<stdio.h>
#include<stdlib.h>
typedef struct edge{
    int i;
    struct edge *next;
}edge;
typedef struct node{
    int i,in;
    edge *next;
}node;
typedef struct gve{
    int v,e;
    node *g;
}gve;
int insert(node *pnode,int i)
{
    edge *new;
    new=(edge *)malloc(sizeof(edge));
    new->i=i;
    new->next=pnode->next;
    pnode->next=new;
    return 0;
}
typedef struct queue{
    int head,tail,size,n;
    node **que;
}queue;
int enqueue(queue *q,node *pnode)
{
    if (q->n==q->size)
    {
        printf("queue overflow!\n");
        return 0;
    }
    q->tail=q->tail==q->size-1?0:q->tail+1;
    q->que[q->tail]=pnode;
    q->n++;
    return 0;
}
int dequeue(queue *q)
{
    if (q->n==0)
    {
        printf("queue empty!\n");
        return 0;
    }
    q->head=q->head==q->size-1?0:q->head+1;
    q->n--;
    return 0;
}
int topological_sort(gve *G)
{
    queue q;
    q.head=0;
    q.tail=-1;
    q.size=G->v;
    q.n=0;
    q.que=(node **)malloc(sizeof(node*)*(q.size));
    int i;
    for (i=1;i<=G->v;i++)
        if (G->g[i].in==0)
            enqueue(&q,&(G->g[i]));
    edge *tmp;
    while (q.n!=0)
    {
        tmp=q.que[q.head]->next;
        while (tmp!=NULL)
        {
            G->g[tmp->i].in--;
            if (G->g[tmp->i].in==0)
                enqueue(&q,&(G->g[tmp->i]));
            tmp=tmp->next;
        }
        printf("%d ",q.que[q.head]->i);
        dequeue(&q);
    }
    return 0;
}
int main(void)
{
    int i;
    gve G;
    scanf("%d%d",&G.v,&G.e);
    G.g=(node *)malloc(sizeof(node)*(G.v+1));
    for (i=1;i<=G.v;i++)
    {
        G.g[i].next=NULL;
        G.g[i].in=0;
        G.g[i].i=i;
    }
    int s,d;
    for (i=1;i<=G.e;i++)
    {
        scanf("%d%d",&s,&d);
        insert(&G.g[s],d);
        G.g[d].in++;
    }
    topological_sort(&G);
    printf("\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值