• C++编程练习(12)----“有向图的拓扑排序“


    设G={V,E}是一个具有 n 个顶点的有向图,V中的顶点序列 v1,v2,......,vn,满足若从顶点 vi 到 vj 有一条路径,则在顶点序列中顶点 vi 必在顶点 vj 之前。则称这样的顶点序列为一个拓扑序列


    在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,称为 AOV 网(Activity On Vertex Network)。


    拓扑排序,其实就是对一个有向图构造拓扑序列的过程。构造时会有两个结果,如果此网的全部顶点都被输出,则说明它是不存在(回路)的 AOV 网;如果输出顶点数少了,哪怕是少了一个,也说明这个网存在环(回路),不是 AOV 网。


    对 AOV 网进行拓扑排序的基本思路是:从 AOV 网中选择一个入度为 0 的顶点输出,然后删除此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者 AOV 网中不存在入度为0的顶点为止。


    具体代码如下:(代码虽然能输出正确答案,但会报错,我自己找不到原因.....还请大家多多指点。

    /*TopologicalSort.h头文件*/
    /*用邻接表的方式建立有向图,并完成拓扑排序*/
    #include<iostream>
    #define OK 1
    #define ERROR 0
    #define MAXVEX 100
    typedef int Status;
    using namespace std;
    
    class EdgeNode{	/*边表结点*/
    public:
    	EdgeNode(){}
    	~EdgeNode();
    	int adjvex;	/*邻接点域,存储该顶点对应的下标*/
    	int weight;	/*用于存储权值,对于非网图可以不需要*/
    	class EdgeNode *next;	/*链域,指向下一个邻接点*/
    };
    
    class VertexNode{	/*顶点表结点*/
    public:
    	VertexNode():in(0),data(0),firstedge(NULL){}
    	~VertexNode();
    	int in;	/*顶点入度*/
    	int data;	/*顶点域,存储顶点信息*/
    	EdgeNode *firstedge;	/*边表头指针*/
    };
    
    class graphAdjList{
    public:
    	graphAdjList(){
    		for (int x=0;x<MAXVEX;x++)
    		{
    			adjList[x] = new VertexNode;
    		}
    	}
    	~graphAdjList();
    	VertexNode* adjList[MAXVEX];
    	int numVertexes,numEdges;	/*图中当前顶点数和边数*/
    };
    
    void CreateALGraph(graphAdjList **G)		/*建立图的邻接表结构*/
    {
    	int i,j,k;
    	EdgeNode *e;
    	cout<<"输入顶点数和边数:"<<endl;
    	cin>>(*G)->numVertexes>>(*G)->numEdges;
    	cin.clear();
    	for(i=0; i<(*G)->numVertexes; i++)
    	{
    		cout<<"输入各顶点信息:"<<endl;
    		cin>>(*(*G)->adjList)[i].data;
    		cin.clear();
    		(*(*G)->adjList)[i].firstedge = NULL;
    		(*(*G)->adjList)[i].in = 0;
    	}
    	for(k=0; k<(*G)->numEdges; k++)
    	{
    		cout<<"输入边(vi,vj)上的顶点序号:"<<endl;
    		cin>>i>>j;
    		cin.clear();
    		++(*(*G)->adjList)[j].in;
    		e = new EdgeNode;
    		e->adjvex = j;
    		e->next = (*(*G)->adjList)[i].firstedge;
    		(*(*G)->adjList)[i].firstedge = e;
    	}
    }
    
    /*拓扑排序,若GL无回路,则输出拓扑排序序列并返回OK,若有回路返回ERROR*/
    Status TopologicalSort(graphAdjList *GL)
    {
    	EdgeNode *e;
    	int i,k,gettop;
    	int top = 0;	/*用于栈指针下标*/
    	int count = 0;	/*用于统计输出顶点的个数*/
    	int *stack = new int[GL->numVertexes];		/*建栈存储入度为0的顶点*/
    	for(i=0; i<GL->numVertexes; i++)
    		if(0 == (*(GL->adjList))[i].in)
    			stack[top++] = i;
    	cout<<"拓扑排序为:"<<endl;
    	while(0 != top)
    	{
    		gettop = stack[--top];	/*出栈*/
    		cout<<(*(GL->adjList))[gettop].data<<" -> ";	/*打印此顶点*/
    		count++;	/*统计输出顶点数*/
    		for(e=(*(GL->adjList))[gettop].firstedge; e; e=e->next)
    		{	/*对此顶点弧表遍历*/
    			k = e->adjvex;
    			if(!(--(*(GL->adjList))[k].in))	/*将k号顶点邻接点的入度减1*/
    				stack[top++] = k;	/*若为0则入栈,以便于下次循环输出*/
    		}
    	}
    	cout<<endl;
    	delete[] stack;
    	if (count < GL->numVertexes)	/*如果count小于顶点数,说明存在环*/
    	{
    		cout<<"存在环"<<endl;
    		return ERROR;
    	}
    	else
    	{
    		cout<<"不存在环"<<endl;
    		return OK;
    	}
    }

    对于如下的有向图:


    运行结果如下:


    但是同时还存在这样一个报错,请大家指点是为什么。。。。感激万分。


  • 相关阅读:
    第二十天笔记
    第十九天笔记
    第十七天笔记
    第十五天笔记
    第十六天笔记
    第十二天笔记
    数字三角形
    最大子段和与最大子矩阵和
    分组背包
    二维背包
  • 原文地址:https://www.cnblogs.com/fengty90/p/3768850.html
Copyright © 2020-2023  润新知