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;
- }
- }
对于如下的有向图:
运行结果如下:
但是同时还存在这样一个报错,请大家指点是为什么。。。。感激万分。
C++编程练习(12)----“有向图的拓扑排序“的更多相关文章
- 有向图和拓扑排序Java实现
package practice; import java.util.ArrayDeque; import java.util.Iterator; import java.util.Stack; pu ...
- 有向图的拓扑排序的理解和简单实现(Java)
如果图中存在环(回路),那么该图不存在拓扑排序,在这里我们讨论的都是无环的有向图. 什么是拓扑排序 一个例子 对于一部电影的制作过程,我们可以看成是一个项目工程.所有的工程都可以分为若干个" ...
- 有向图的拓扑排序算法JAVA实现
一,问题描述 给定一个有向图G=(V,E),将之进行拓扑排序,如果图有环,则提示异常. 要想实现图的算法,如拓扑排序.最短路径……并运行看输出结果,首先就得构造一个图.由于构造图的方式有很多种,这里假 ...
- 拓扑排序(topsort)
本文将从以下几个方面介绍拓扑排序: 拓扑排序的定义和前置条件 和离散数学中偏序/全序概念的联系 典型实现算法解的唯一性问题 Kahn算法 基于DFS的算法 实际例子 取材自以下材料: http://e ...
- [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 ...
- 数据结构之---C语言实现拓扑排序AOV图
//有向图的拓扑排序 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <string.h> #define ...
- python 排序 拓扑排序
在计算机科学领域中,有向图的拓扑排序是其顶点的先行排序,对于每个从顶点u到顶点v的有向边uv,在排序的结果中u都在v之前. 如果图是有向无环图,则拓扑排序是可能的(为什么不说一定呢?) 任何DAG具有 ...
- Wannafly挑战赛22 B 字符路径 ( 拓扑排序+dp )
链接:https://ac.nowcoder.com/acm/contest/160/B 来源:牛客网 题目描述 给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符 ...
- puk2367 拓扑排序
Description The system of Martians' blood relations is confusing enough. Actually, Martians bud when ...
随机推荐
- Spring 工作原理
1.spring原理 内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建.调用对象,Spring就是在运 ...
- IT技术网站汇总
首先是比较著名的博客型的网站!一般来说在国外比较著名的博客基本上都是比较有影响力发起的或者建立的经常发布一些比较有思考力深入分析的文章! 博客媒体网站 1.www.ArsTechnica.com 2. ...
- IOS FMDB模糊查询
http://blog.sina.com.cn/s/blog_9630f1310101fx1d.html /查询记录 -(NSArray*)selectitemDream_desc:(JiemengS ...
- 在JSP里使用CKEditor和CKFinder
在JSP里使用CKEditor和CKFinder 最 近在做一个新闻发布平台,放弃了很早的FCKEditor,使用CKEditor和CKFinder,尽管免费的CKFinder是Demo版本,但是功 ...
- UDP网络程序模型设计
UDP网络程序设计 1. UDP网络编程模型程序初始化 1.1服务器使用的函数 创建socket----->socket 绑定地址-------->bind 接受数据--------> ...
- iOS中UITextField 使用全面解析 分类: ios技术 2015-04-10 14:37 153人阅读 评论(0) 收藏
//初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 13 ...
- iOS调试-LLDB学习总结
from:http://www.jianshu.com/p/d6a0a5e39b0e LLDB阐述 LLDB 是一个有着 REPL 的特性和 C++ ,Python 插件的开源调试器.LLDB 绑定在 ...
- Makefile常用调试方法
转载自 陈皓<跟我一起写 Makefile><GNU Make项目管理> GNU make 提供了若干可以协助调试的内置函数以及命令行选项. 1.warning函数 $(war ...
- 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务)的有关问题
[转]http://www.myexception.cn/program/1964906.html 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务 ...
- 在PHP语言中使用JSON
目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它. 我写过一篇<数据类型和JSON格式>,探讨它的设计思想.今天,我想总结一下PHP语言对它的支持,这是开发 ...