设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;
}
}

对于如下的有向图:

运行结果如下:

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

C++编程练习(12)----“有向图的拓扑排序“的更多相关文章

  1. 有向图和拓扑排序Java实现

    package practice; import java.util.ArrayDeque; import java.util.Iterator; import java.util.Stack; pu ...

  2. 有向图的拓扑排序的理解和简单实现(Java)

    如果图中存在环(回路),那么该图不存在拓扑排序,在这里我们讨论的都是无环的有向图. 什么是拓扑排序 一个例子 对于一部电影的制作过程,我们可以看成是一个项目工程.所有的工程都可以分为若干个" ...

  3. 有向图的拓扑排序算法JAVA实现

    一,问题描述 给定一个有向图G=(V,E),将之进行拓扑排序,如果图有环,则提示异常. 要想实现图的算法,如拓扑排序.最短路径……并运行看输出结果,首先就得构造一个图.由于构造图的方式有很多种,这里假 ...

  4. 拓扑排序(topsort)

    本文将从以下几个方面介绍拓扑排序: 拓扑排序的定义和前置条件 和离散数学中偏序/全序概念的联系 典型实现算法解的唯一性问题 Kahn算法 基于DFS的算法 实际例子 取材自以下材料: http://e ...

  5. [ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)

    Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...

  6. 数据结构之---C语言实现拓扑排序AOV图

    //有向图的拓扑排序 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <string.h> #define ...

  7. python 排序 拓扑排序

    在计算机科学领域中,有向图的拓扑排序是其顶点的先行排序,对于每个从顶点u到顶点v的有向边uv,在排序的结果中u都在v之前. 如果图是有向无环图,则拓扑排序是可能的(为什么不说一定呢?) 任何DAG具有 ...

  8. Wannafly挑战赛22 B 字符路径 ( 拓扑排序+dp )

    链接:https://ac.nowcoder.com/acm/contest/160/B 来源:牛客网 题目描述 给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符 ...

  9. puk2367 拓扑排序

    Description The system of Martians' blood relations is confusing enough. Actually, Martians bud when ...

随机推荐

  1. (中等) POJ 2886 Who Gets the Most Candies? , 反素数+线段树。

    Description N children are sitting in a circle to play a game. The children are numbered from 1 to N ...

  2. Eclipse 的 git 插件操作 "代码提交"以及"代码冲突"

    面向对象:曾经使用过SVN的同学. (因为Git 它 可以说是双重的SVN (本地一个服务器,远程一个服务器)),提交代码要有两次步骤,先提交到本地服务器,再把本地服务器在提交到远程服务器. 所以连S ...

  3. dedecms标签使用

    关键描述调用标签: <meta name="keywords" content="{dede:field name='keywords'/}">&l ...

  4. WKWebKit基础

    UIWebView & UIWebViewDelegate 这个两个东西在 WKWebKit 中被重构成 14 个类 3 个协议. WKWebKit Framework Classes WKB ...

  5. FZU 1054 阅读顺序

    水题,倒着输出. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm& ...

  6. 阿里开源Mysql分布式中间件:Cobar

    目前在从事数据库中间件的开发和维护工作,我们使用的数据库中间件就是由cobar改造而来,所以对于cobar的一些说明一看就明白了: 下面是看到的一个很不错的分析文档 这里整理了下方便自己学习使用. C ...

  7. X-004 FriendlyARM tiny4412 uboot移植之点亮指路灯

    <<<<<<<<<<<<<<<<<<<<<<<<< ...

  8. Selenium2+Python:Webdriver API速记手册

    由于web自动化常常需要控制浏览器行为和操作页面元素,相关函数又比较多,于是再此记下一份Webdriver API查阅文档以备不时之需. 参考:虫师<Selenium2自动化测试实战>,和 ...

  9. FTP-使用记录

    1.磁盘配额不够用 Could not write to transfer socket: ECONNABORTED - 连接中止 452-Maximum disk quota limited to ...

  10. Java Spring MVC项目搭建(三)——“Hello World”

    在Spring 的配置文件里,我们定义了一个bean ,Spring 会在启动时候会生成对象. <bean id = "helloworld" class="com ...