第2关:基于邻接表完成拓扑排序

任务描述
相关知识
拓扑排序的思路
编程要求
测试说明
任务描述
本关任务:基于邻接表完成图的拓扑排序。


相关知识
除了邻接矩阵外,邻接表也可以表达图。邻接表给每个顶点建立一个链表,链表元素是该点的所有出边或者所有入边(只记录了每边的另外一个端点),构成出边邻接表或入边邻接表。
通过邻结表也可以完成图顶点的拓扑排序。

拓扑排序的思路
第1步,i=0;
第2步,找到1个入度为0的点v,把它排在order[i]中,i++
第3步,在图中去掉点v,以及点v的出边,对剩余的图回到第2步处理, 直到i>=总结点数,完成所有顶点排序。

编程要求
根据提示,在右侧编辑器补充代码,实现拓扑排序int TopSort(int n,  LinkList* InAdjTable[],  LinkList* OutAdjTable[], int order[]), 其中邻接表应用以前的单链表技术。
给了你出边邻接表和入边邻接表,其实只要一个就可以,为了方便都给你了。将顶点序号填写在数组order中。注意不要删除或添加邻接表的结点,如何去掉已排序顶点想其他办法。

测试说明
平台会对你编写的代码进行测试.

开始你的任务吧,祝你成功!

 #include <stdio.h>
#include <string.h>
#include "LinkList.h"
#define N 7
#define M 10
LinkList* OutAdjTable[N];
LinkList* InAdjTable[N];
int edge[M][2]={
{0,1},
{0,2},
{1,3},
{2,3},
{2,4},
{3,5},
{3,6},
{4,3},
{4,5},
{5,6}
};

int CreateAdjTable(){
	int i,j, start, end;
	for(i=0;i<N;i++){
		 OutAdjTable[i]=LL_Create();
		 InAdjTable[i]=LL_Create();
	}	
	
	for (i=0;i<M;i++){		
		LL_InsAfter(OutAdjTable[edge[i][0]],edge[i][1]);
		LL_InsAfter(InAdjTable[edge[i][1]],edge[i][0]);
	}
}
typedef struct node{
    int vex;
    struct node *next;
}JD;
typedef struct tnode{
    int vexdata;
    int in;
    struct node *link;
}TD;
void CreateDG(TD G[N])
{
     int i,j,k;
     int v1,v2;
     JD *pi,*pj;
     for(i=0;i<N;i++)
     {
         G[i].vexdata=i;
         G[i].link=NULL;
     }
     for(k=0;k<M;k++)
     {
         i=edge[k][0];
         j=edge[k][1];
         pi=new JD;
         pi->vex=j;
         pi->next=G[i].link;
         G[i].link=pi;
     }
}

int TopSort(int n,  LinkList* InAdjTable[],  LinkList* OutAdjTable[], int order[]){
//输入n是图顶点个数,InAdjTable是入边邻接表,OutAdjTable是出边邻接表,给两个表是为了方便你使用。
//你把排序结果填入order数组中。
int top,m,k,j,s[M];
JD *p;
TD g[N];
CreateDG(g);
for(k=0;k<N;k++)
{
    g[k].in=0;
}
for(k=0;k<N;k++)
{
    g[edge[k][1]].in+=1;
}
for(k=0;k<N;k++)
{
    m=0;
    p=g[k].link;
    while(p)
    {
        m=0;p=p->next;
    }
    OutAdjTable[k]->len=m;
}
top=-1;
m=0;
for(j=0;j<=N;j++)
if(g[j].in==0)  s[++top]=j;

while(top>=0)
{
    j=s[top--];
    order[m++]=j;

    p=g[j].link;
    while(p!=NULL)
    {
        k=p->vex;
        g[k].in--;
        if(g[k].in==0)  s[++top]=k;
        p=p->next;
    }
}
if(m<n)  return 0;
return 1;
}

仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值