拓朴排序

来源:互联网 发布:暗黑启示录2java破解版 编辑:程序博客网 时间:2024/04/28 03:56
 
#include<iostream.h>
//图的邻接表不是唯一的,因为在每个顶点的邻接表中,各边结点的链接次序可以任意安排,
//其具体链接次序与边的输入次序和生成算法有关。

//下面给出建立图的邻接表的有关类型定义和生成一个有向图邻接表的算法描述
typedef int VertexType;//这里有分号 #define才没有分号
const int MaxVertexNum=20;//{图的最大顶点数,它应不小于具体图的顶点数n};
const int MaxEdgeNum=30;//{图的最大边数,它应不小于具体图的最大边数e};
typedef VertexType vexlist[MaxVertexNum];//定义vexlist为存储顶点信息的数组类型
struct edgenode//定义邻接表中的边结点类型
{
    int adjvex;//邻接点域
    int weight;//权值域,对无权图可省去
    edgenode *next;//指向下一个边结点的链域
};//边忘了这个分号
typedef edgenode *adjlist[MaxVertexNum];//这义adjlist为存储n个表头指针的数组类型

void Create2(vexlist GV,adjlist GL,int n,int e)    //看看GL到底是什么: GL[i]->adjvex
         //通过从键盘上输入的n个顶点信息和e条有向边的信息
         //建立顶点数组GV和邻接表GL
{
    int i,j,k,w;
    //建立顶点数组
    cout
<<"输入"<<n<<"个顶点"<<endl;
    for(i
=0;i<n;i++)
        
cin>>GV[i];
    //初始化邻接表,即将表头向量中的每个域置空
    for(i=0;i
<n;i++)
        GL[i]
=NULL;
    
//建立邻接表
    cout<<"输入"<<e<<"条边"<<endl;
    for(k
=1;k<=e;k++)
    
{
        //输入一条边<i,j
>
        cin>>i>>j;//>>w;
        //由系统分配一个新结点
        edgenode *p=new edgenode;
        //将j的值赋给新结点的邻接点域
        p->adjvex=j;
        //p->weight=w;
        //将新结点插入到vi邻接表的表头
        p->next=GL[i];
        GL[i]=p;
    }
}
void Toposort(adjlist GL,int n)//此算法的时间复杂度为o(n+e) //n为顶点数,e为边数
       //利用邻接表GL表示的有向图进行拓朴排序
{
    
    int i,j,k,top,m=0;//m用来统计拓朴序列中的顶点
    //top的值为一个入度为0的顶点序号,top指向的值为下一个入度为0的顶点序号
    edgenode *p;
    //定义存储图中每个顶点入度的一维整型数组d
    int *d=new int[n];
    //初始化数组d中的每个元素值为0
    for(i=0;i
<n;i++)
        d[i]
=0;
    
//利用数组d中的对应元素统计出每个顶点的入度
    for(i
=0;i<n;i++)
    
{
        p
=GL[i];
        
while(p!=NULL)
        
{
            j
=p->adjvex;
            d[j]++;
            p=p->next;
        }
    }
    //初始化用于链接入度为0的元素的栈的栈顶指针top为-1
    top=-1;
    //建立初始化栈
    for(i=0;i
<n;i++)
        if(d[i]
==0)
        
{
            d[i]
=top;
            
top=i;
        
}
        //每循环一次删除一个顶点及所有出边
        cout<<"拓朴序列如下:"<<endl;
    while(top!
=-1)
    
{
        j
=top;//j的值为一个入度为0的顶点序号
        
top=d[top];//删除栈顶点元素
        
cout<<j<<" ";//输出一个顶点
        m++;//输出的顶点个数加1
        p
=GL[j];//p指向vj邻接点表的第一个结点
        
while(p!=NULL)
        
{
            k
=p->adjvex;//vk是vj的一个邻接点
            d[k]--;//vk的入度减1
            if(d[k]==0)//把入度为0的元素进栈
            {
                d[k]=top;
                top=k;

            }
            p=p->next;//p指向vj邻接点表的下一个结点
        }

    }
    cout
<<endl;
    if(m<n)//当输出的顶点数小于图中的顶点数时,输出有回路信息(拓朴图是无回路的,因
        //为若带有回路,则回路上的所有活动都无法进行)
    {
        cout<<"The network has a cycle!"<<endl;
    }
}

void main()
{
    vexlist GV;
    adjlist GL;

    int n
=6;
    
int e=8;
    
Create2(GV,GL,n,e);
    //cout<<GL[0]-
>adjvex;
    Toposort(GL,n);
}
//测试用例如下:
/*
输入6个顶点
0 1 2 3 4 5
输入8条边
0 2
1 2
1 3
1 4
2 3
3 5
4 5
2 5
拓朴序列如下:
1 4 0 2 3 5
*/

/*
http://java2.xinwen365.net

QQ群:
34409541 讨论网页  
34409326 讨论JAVA 已满 
34408784 讨论VC++  
34409699 讨论VC++  
9143041 讨论MFC编程  
10614204 讨论C#  
10613030 讨论Win32编程  
10613067 讨论游戏开发  
18779860 讨论JAVA  
*/
原创粉丝点击