设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. 缩短url-url短地址链接

    之前给合作方二维码时隐藏的url过长,导致合作方提出在打印的时候打印不出来的问题,要求url长度在50字节内,所以写了缩短url功能. var url = string.Format("{0 ...

  2. CentOS 7 x64 安装 Ceph

    CentOS 7  x64 安装 Ceph 二, 实验环境 节点            IP                 主机名                  系统 MON         1 ...

  3. Spring自学教程-IOC、DI、AOP(二)

    一.spring的IOC-就是怎样使用spring来创建对象 二.springDI(依赖注入)-就是怎样给属性赋值 通过set方式赋值 以下我们只需要记住两点的赋值,基本类型和引用类型的赋值 基本类型 ...

  4. 8、手把手教你Extjs5(八)自定义菜单2

    这一节来定义另外三种类型的菜单类.首先定义菜单按钮类.文件放于app/view/main/region目录下面,文件名为ButtonMainMenu.js. /** * 显示在顶部的按钮菜单,可以切换 ...

  5. 使用Emacs中的org-mode写cnblogs之图片插入

    .title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium ...

  6. ASP.NET异步处理

    前一篇:详解 .NET 异步 在前文中,介绍了.NET下的多种异步的形式,在WEB程序中,天生就是多线程的,因此使用异步应该更为谨慎.本文将着重展开ASP.NET中的异步. [注意]本文中提到的异步指 ...

  7. Beautiful Soup 定位指南

    Reference: http://blog.csdn.net/abclixu123/article/details/38502993 网页中有用的信息通常存在于网页中的文本或各种不同标签的属性值,为 ...

  8. 微信和QQ网页授权登录

    一:微信授权 //用户授权 public function is_weixin(){ $url = "https://open.weixin.qq.com/connect/oauth2/au ...

  9. 我对CSS中的BFC的理解

       1.什么是BFC 其实在老师让我们写这篇叫BFC的时候,我跟本不知道有什么BFC的东西. 后来,我找了一些资料,知道了,BFC是Block Formatting Context (块级格式化上下 ...

  10. session锁问题

    碰到个问题,在使用了session时(如用户登录),如果当前请求时间过长,再执行其他请求都不会有响应,查找了网上资料发现,这个是session锁的问题 目前我们的程序基本流程如下: (1)加载Sess ...