拓扑排序

//拓扑排序

#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define MAX 20
typedef struct arcnod  //表结点定义
{
 int adjvex;
 struct arcnod *nextarc;
}arcnode;
typedef struct vnode  //表头结点类型
{
 int data;  //定点信息
 int indegree;  //该点的入度
 arcnode *firstarc; //指向第一个表节点
}vnode,adjlist[MAX];
typedef struct
{
 adjlist vertices;   
 int vexnum,arcnum;  //图的顶点和边的个数
 int kind;           //图的类型
}graph; //定义一个邻接表的存储结构

typedef struct  //定义一个栈的结构
{
 int *top;
 int *base;
 int nowsize;
}stack;

int emptystack(stack &s) //判断栈是否为空的函数
{
 if(s.nowsize==0)return 1;
 else return 0;
}
void initstack(stack &s) //构造一个空栈的函数
{
 s.base=s.top=(int *)malloc(MAX*sizeof(int));
 s.nowsize=0;
}
void pushstack(stack &s,int e) //入栈
{
 *s.top=e;
 s.top++;
 s.nowsize++;
}
void popstack(stack &s,int &e)  //出栈
{
 e=*(--s.top);
 s.nowsize--;
}

int location(graph G,int n)  //找出值为n的顶点在存储矩阵中的索引
{
 int i;
 for(i=0;i<G.vexnum;++i)
 {
  if(n==G.vertices[i].data)return i;
 }
 return -1; //无匹配值时返回-1
}
//构造有向图的函数
void creatDG(graph &G)
{
 int i,n,k;
 arcnode *p1,*p2;
 printf("输入顶点和边的个数:/n");
 scanf("%d%d",&G.vexnum,&G.arcnum);
 printf("输入各顶点的值:/n");
 for(i=0;i<G.vexnum;++i)
 {scanf("%d",&G.vertices[i].data);}
   
 for(i=0;i<G.vexnum;++i)
 {
  printf("输入与%d关联的顶点:",G.vertices[i].data);
  scanf("%d",&n);
  if(n==-1){G.vertices[i].firstarc=0;continue;}
  k=location(G,n);
  p1=(arcnode *)malloc(sizeof(arcnode));
  p1->adjvex=k;
  p1->nextarc=0;
   G.vertices[i].firstarc=p1;
   printf("输入与%d关联的顶点:",G.vertices[i].data);
   scanf("%d",&n); 
   k=location(G,n);
     while(n!=-1)
     {
      p2=(arcnode *)malloc(sizeof(arcnode));
      p2->adjvex=k;
      p2->nextarc=0;
      p1->nextarc=p2;
      p1=p2;
      printf("输入与%d关联的顶点:",G.vertices[i].data);
      scanf("%d",&n);
      k=location(G,n);
     }
 }
}

//计算图中各个顶点的入度并赋值给该顶点的indegree
void findindegree(graph &G)
{
 int i,j;
 arcnode b1;
    arcnode *p1=&b1,*p2;
 for(i=0;i<G.vexnum;++i)
  G.vertices[i].indegree=0;  //初始化各个节点的入度为0

 for(i=0;i<G.vexnum;++i)
  {
   p1=G.vertices[i].firstarc;
   while(1)
   {
        if(p1)
    {G.vertices[p1->adjvex].indegree++;
    p1=p1->nextarc;
    }
    if(p1==0)break;  //如果到了尾链,则选择下一个头节点开始
   }
  }
}

 

//输出图中各个顶点的入度的函数
void print(graph G)
{
 for(int i=0;i<G.vexnum;++i)
  printf("顶点%d的入度是 %d/n",G.vertices[i].data,G.vertices[i].indegree);
}


//拓扑排序算法
int topo(graph &G)
{
 int i,count,k,n;
 arcnode *p;
 stack s;
 findindegree(G);
 initstack(s);
 for(i=0;i<G.vexnum;++i)
  if(G.vertices[i].indegree==0)pushstack(s,i);
 count=0;
 while(!emptystack(s))
 {
  popstack(s,n);
  printf("%d ",G.vertices[n].data);
  ++count;
  for(p=G.vertices[n].firstarc;p;p=p->nextarc)
  {
   k=p->adjvex;
      if(!(--(G.vertices[k].indegree)))pushstack(s,k);
  }
 }
 if(count<G.vexnum)return 0;  //说明此图为有环
 else return 1; 
}

void main()
{
 int i;
 graph g;
 creatDG(g);
 findindegree(g);
    print(g);
    i=topo(g);
    if(i==0)printf("此有向图有环./n");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值