拓扑排序

#include<iostream>    
#include<algorithm>  
#include<stack>  
#include<memory.h>   
#define MAX 10000
#define OK  1 
using namespace std; 
stack<int>mystack;  
int indegree[MAX];  
struct node   
{  
    int  adjvex;  
    struct node *next;  
}adj[MAX];  
 
int Create(node adj[],int n,int m)            //邻接表建表函数,n代表顶点数,m代表边数  
{  
    int i;  
    node *p;  
    for(i=1;i<=n;i++)  
    {   
        adj[i].adjvex=i;  
        adj[i].next=NULL;  
    }  
    for(i=1;i<=m;i++)  
    {  
        cout<<"输入第"<<i<<"条边:";  
        int u,v;  
        cin>>u>>v;  
        p = new node;  
        p->adjvex = v;  
        p->next   = adj[u].next;  
        adj[u].next = p;  
    }  
    return OK;  
}  

void print(int n)   //n代表顶点数  
{     
    int i;  
    node *p;  
    for(i=1;i<=n;i++)  
    {  
            p = &adj[i];  
        while(p!=NULL)  
        {  
            cout<<p->adjvex<<' ';  
            p=p->next;  
        }  
        cout<<endl;  
    }  
}
  
/*拓扑排序*/ 
void topsort(node adj[],int n)  
{  
  
    int i;  
    struct node *p;  
    memset(indegree,0,sizeof(indegree));  
    for(i=1;i<=n;i++)  
    {  
  
        p = adj[i].next;  
        while(p!=NULL)  
        {  
            indegree[p->adjvex]++;  
            p=p->next;  
        }  
    }  
	 //入度为0的入栈 
    for(i=1;i<=n;i++)  
    {  
  
        if(indegree[i]==0)      
            mystack.push(i);  
    }  
    int count = 0;  
    while(mystack.size()!=0)  
    {  
  
        i = mystack.top();  
        mystack.pop();  
        cout<<i<<' ';   //输出源点(入度为0) 
        count++;       
        for(p=adj[i].next;p!=NULL;p=p->next)  
        {  
            int k = p->adjvex;  
            indegree[k]--;        //对应的入度数量要减 1
            if(indegree[k]==0)   //入度为0则入栈 
                mystack.push(k);  
        }  
    }  
       cout<<endl;
	   /*如果入度为源点栈为空,但图还有剩余元素则判断有环(count记录输出的顶点数量不等于图的顶点数)*/   
    if(count<n){ 
	   cout<<"有回路"<<endl;  
	} 
}  
  
int main()  
{  
    int n;  
    int m;  
    cout<<"请输入顶点数及边数:";  
    cin>>n>>m;  
    Create(adj,n,m);  
    cout<<"输入的邻接表为:"<<endl;  
    print(n);  
    cout<<"拓扑排序结果为:"<<endl;  
    topsort(adj,n);  
    return 0;  
}

//对应顶点输入的情况

/*拓扑排序:入度为0的输出,由它指向的相关的边删除,在此基础上讨论其他顶点的入度情况*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_VERTEX_NUM 20
#define OVERFLOW 0
#define OK 1
#define TRUE 1  
#define FALSE 0
#include<stack>
#define MAX 10000 
using namespace std;
typedef  int   Status  ;
typedef  char VertexType;
typedef  int  QElemType;
typedef struct ArcNode
{
     int adjvex;              			  //邻接点域,存储该邻点顶点对应的下标
     struct ArcNode *nextarc;			 //邻节点
     int weight;    					//权值
}ArcNode;
/*邻接表结构*/
typedef struct VNode
{
     VertexType data;	   			//顶点对应的值
     ArcNode  *firstarc;            //边表头指针指向邻顶点
}VNode,AdjList[MAX_VERTEX_NUM];

typedef struct
{
     AdjList  vertices;  
     int vexnum,arcnum;			    //顶点数,边数
}ALGraph;

void CreateALGraph(ALGraph *G)    //构建图
{
     ArcNode *p;
     int i,j,k;
     printf("输入顶点与边的数目:\n");
     scanf("%d%d",&G->vexnum,&G->arcnum);
     getchar();
     printf("输入顶点值:\n");
    for(i=1;i<=G->vexnum;i++)
    {
          //printf("input %dth vex(char) :\n");
          scanf("%c",&G->vertices[i].data);
          getchar();
          G->vertices[i].firstarc=NULL;
    }
    //建立边表
    printf("输入邻接表对应的下标:\n");
    for(k=1;k<=G->arcnum;k++)
    {
          scanf("%d%d",&i,&j);   //边对应的两个顶点下标并将俩顶点联系起来
          p = (ArcNode *)malloc(sizeof(ArcNode));
          p->adjvex = j;
          p->nextarc = G->vertices[i].firstarc;
          G->vertices[i].firstarc = p;
    }
}
/*记录各顶点的入度情况*/
void FindIndgree(ALGraph G,int Indegree[MAX]){
    memset(Indegree,0,sizeof(Indegree));
	ArcNode *p;

	for(int i = 1;i<=G.vexnum;i++){ 
        p = G.vertices[i].firstarc; 
        while(p)  
        {  
            Indegree[p->adjvex]++;  
            p = p->nextarc;  
        }  
    }     
}

void Topological_Sort(ALGraph G){	
   stack<int> s;
   ArcNode *p;
   int count = 0;
   int Indegree[MAX];
   FindIndgree(G,Indegree);
   /*入度为0的入栈*/
    for(int i = 1;i<=G.vexnum;i++){
   	    if(!Indegree[i]){
   	   	    s.push(i);
		}
    }
    while(!s.empty()){
   	    int item = s.top();
   	    printf("%c ",G.vertices[item].data);
   	    s.pop();
   	    count++; 
   	    for(p=G.vertices[item].firstarc;p;p=p->nextarc){                                              
   	        int k = p->adjvex;                   
			if(!(--Indegree[k]))  	s.push(k);   /*(--Indegree[k])是指原来指向它的那个指向边撤去,如果此时该顶点对应的入度为0,则入栈*/
		}
    }
    if(count<G.vexnum){
   	  printf("有回路:\n");
    }
    
}
int main(){
	ALGraph G;
	CreateALGraph(&G);  
 	printf("拓扑排序为:\n"); 
	Topological_Sort(G);
	return 0; 
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值