邻接表储存的图拓扑排序

拓扑排序,可以检查图中是否存在环,若图中的顶点都在他的 拓扑排序中,则它不存在环,若有的点不存在拓扑排序序列中,不在序列的结点存在环,或者它在环之中。

//拓扑排序 
#include<iostream>
#define  max 100
#define maxint 32726
#define  maxvex 100
using namespace std ;
typedef struct stack{
	char *base;
	char *top;
	int maxsize;
}Stack;
//定义栈 
void initstack(Stack &S){
	 S.base=new char [max];
	 if(!S.base){
	 	return ;
	 } 
	 S.top=S.base;
	 S.maxsize=max;	 
}
//入栈 
char pushstack(Stack &S ,char e){
	if(S.top-S.base==S.maxsize){
		printf("栈已满\n");
		return 0;
	}
	*S.top++=e;
} 
//出栈 
char popstack (Stack &S){
	char e;
	if(S.top==S.base){
		printf("栈已空\n");
		return 0; 
	}
	e=*--S.top;
	return e;
}
//判断栈空
int emptystack(Stack &S){
	if(S.top==S.base)
	  return 1;
	  else return 0;
} 
//边节点 
typedef struct vexnode {
	int adjvex;
	char v;
	struct  vexnode *nextarc;
	float info;
}ArNode;
typedef struct Vnode {  //顶点信息 
	char data;
	ArNode *firstarc; //指向第一个边结点 
}Vonde,Adjust[100]; 
typedef struct {
	Adjust survice;//邻接表 
	int vexnum,acrnum;//图的当前顶点数和边数 
}ALgraph;
//邻接表查找UND
 int locate1(ALgraph&R, char v,int n){
 	int j,i;
 	for(i=1;i<=n;i++){
 		if(R.survice[i].data==v){
 			j=i;
		 }
	 }
	 return j;
 } 
void creatUND(ALgraph &R){
	char v1,v2;
	int i1,i2;//两个顶点的位置和权值 
	float i3;
	printf("请输入顶点数和边数:"); 
	cin>>R.vexnum>>R.acrnum; //输入顶点数和边数 
	printf("请输入各个顶点的值:\n"); 
	for(int i=1;i<=R.vexnum;i++){
		cin>>R.survice[i].data;//输入各个顶点的信息 
		R.survice[i].firstarc=NULL;
		 
	}
   
    printf("请输入每条边依附的两个结点和权值:\n");
	for(int i=1;i<=R.acrnum;i++){
		cin>>v1>>v2>>i3;
	    
		i1=locate1(R,v1,R.vexnum);
		i2=locate1(R,v2,R.vexnum);
		ArNode *p1=new ArNode;
		p1->adjvex=i1;//记录顶点的位置 
		p1->info=i3;//记录权值 
		p1->v=v2;//记录边点的值 
		p1->nextarc=R.survice[i1].firstarc;
		R.survice[i1].firstarc=p1;// 将新节点*p2插入顶点Vi1的邻接表中 
	} 
	     ArNode *p2; 
         for(int i=1;i<=R.vexnum;i++){
		 p2=R.survice[i].firstarc;
		while(p2){
			printf("<%c , %c> : %.1f   ",R.survice[i].data,p2->v,p2->info);
			p2=p2->nextarc;
		}
		printf("\n");

}
} 
  //拓扑排序
  void Toposort(ALgraph &R ,Stack &S){
  	int degree[R.vexnum+1]={0};//记录各个结点的入度 
  	char topo[R.vexnum];//排序之后存入的数组 
  	    ArNode *p; 
  	   for(int i=1;i<=R.vexnum;i++){//遍历将各个结点的入度记录在数组中 
  		    p=R.survice[i].firstarc;
  		    while(p){
  		    	int b=locate1(R,p->v,R.vexnum);
  		    	degree[b]++;
  		    	p=p->nextarc;
			  } 
	  }
	  char s;//入度为零的结点 
	  char m;//出栈元素 
	  int k=0,u; 
	  initstack(S);
	  for(int i=1;i<=R.vexnum;i++){//将顶点入度为零的点入栈 
	  	if(degree[i]==0){
	  		 s=R.survice[i].data;
	  		 pushstack(S,s);
		  }
	  }
	  ArNode *p1;
	  //栈非空的情况下进行以下操作 
	  while(!emptystack(S)){
	  	m=popstack(S);//栈顶元素出栈 
	    topo[k]=m;//把输出的元素放到此数组中 
	    k++;//下标进行加加 
	    u=locate1(R,m,R.vexnum);//找到此顶点的下标,让其入度减一 
		degree[u]--;
		p1=R.survice[u].firstarc;//访问它的临结点 
		while(p1){
			degree[locate1(R,p1->v,R.vexnum)]--;//让输出结点的临结点的入度减一
			if(degree[locate1(R,p1->v,R.vexnum)]==0){//如果临结点的入度等于零的话,让其进栈 
				pushstack(S,p1->v);
			}
			p1=p1->nextarc; 
		}
		/*for(int i=1;i<=R.vexnum;i++){
			if(degree[i]==0){
				pushstack(S,R.survice[i].data);
			}
		} */
	  }
	  printf("拓扑排序结果为:"); 
	  for(int i=0;i<k;i++){
	  	printf("%c " ,topo[i]);
	  }
	  printf("\n");
	  if(k<R.vexnum-1){
	  	printf("该有向图有环\n");
	  }else{
	  	printf("该有向图没环\n"); 
	  } 
	   
	  
  } 
/*
输入顶点数  6 边数 8
各个顶点的值 1 2 3 4 5 6 7 8
分别输入的顶点和权值 
1 2 1
1 4 1
1 3 1
3 2 1
3 5 1
4 5 1
6 4 1
6 5 1
*/

int main(){
	Stack S; 
	ALgraph R;
	creatUND(R);
	Toposort(R ,S);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值