关于拓扑排序(topologicalsort)
假设我们有一组任务要完成,并且有些任务要在其它任务完成之后才能开始,所以我们必须非常小心这些任务的执行顺序。
如果这些任务的执行顺序足够简单的话,我们可以用链表来存储它们,这是一个很好的方案,让我们可以准确知道任务的执行顺序。问题是有时候不同任务之间的关系是非常复杂的,有些任务依赖于两个甚至更多的任务,或者反过来很多任务依赖自己。
因此我们不能通过链表或者树的数据结构来对这个问题建模。对这类问题唯一合理的数据结构就是图。我们需要哪种图呢?很显然,我们需要有向图来描述这种关系,而且是不能循环的有向图,我们称之为有向无环图。要通过拓扑排序对图形进行排序,这些图必须是不能循环和有向的。为什么这些图不能循环呢?答案很明显,如果图形是循环的,我们无法知道哪个任务该优先执行,也不可能对任务进行排序。现在我们一要做的是对图中的每个节点排序,组成一条条边(u,v),u在v之前执行。然后我们就可以得到所有任务的线性顺序,并按这种顺序执行任务就一切都OK了。
例如,下面的图的一个拓扑排序是“5 4 2 3 1 0”。一个图可以有多个拓扑排序。
另一个拓扑排序是“4 5 2 3 1 0”。拓扑排序的第一个顶点总是入度为0。

-------------------------------------------------------------------------------------------------------------------------------------------
1.思想先找一个入度为零的访问
接着把它和它的路线删除.....................
但我们并没有真正把它删除,把访问过的入队即可并标记, 随后把与它相邻的元素入度减一即可!!!!
------------------------------
//topologicalsort 排序的实现 容器队列 #include <cstdio>
#include <cstdlib>
//#define _OJ_
#define maxsize 100
int visit[100]; //用来标记已被访问的元素
typedef struct Queue1
{
int top;
int base;
int *elem; //定义队列尊循先进先出的原则
} Queue1, *Queue; typedef struct Graph1
{
int nv;
int ne;
int G[100][100];
} Graph1, *Graph; Queue
creat_Queue(void)
{
Queue q;
q = (Queue) malloc (sizeof(Queue1));
q->elem = (int*) malloc (sizeof(int) * maxsize);
q->top = q->base = 0;
return q;
} int
isempty(Queue q)
{
if(q->top == q->base)
return 1;
else
return 0;
} void
Enqueue(Queue q, int data)
{
q->elem[q->top++] = data;
} int
Dequeue(Queue q)
{
return q->elem[q->base++];
} Graph
creat_Graph(void)
{
int v1, v2, i, j;
Graph g;
g = (Graph) malloc (sizeof(Graph1));
scanf("%d %d", &(g->nv), &(g->ne));
for(i = 1;i <= g->nv; i++) {
for(j = 1;j <= g->nv; j++) {
g->G[i][j] = 0;
}
} for(i = 1;i <= g->ne; i++) {
scanf("%d %d", &v1, &v2);
g->G[v1][v2] = 1;
} return g;
} int
Topologicalsort(Graph g)
{
Queue q;
int i, j, i1, cnt = 0;
int indegree[100];
q = creat_Queue(); for(i = 1;i <= g->nv ; i++) {
indegree[i] = 0; //用一个临时数组来记录入度即每一列非零元素
for(j = 1;j <= g->nv; j++) {
if(g->G[j][i] != 0) ++indegree[i];
}
if(indegree[i] == 0) {Enqueue(q, i); visit[i] = 1;}
} //度为零那么入队并标记 while (isempty(q) != 1) {
i1 = Dequeue(q); printf("i1 == %d\n", i1); cnt++;//cnt用于记录走过的元素
for(i = 1;i <= g->nv; i++) { //把与出队相邻的元素入度减一
if(g->G[i1][i] != 0) indegree[i]--;
if(indegree[i] == 0 && visit[i] == 0) {Enqueue(q, i); visit[i] = 1;}
}
} if(cnt < g->nv) printf("error\n"); //若从cnt< g->nv者出错表示图中有回路
} // void
// print(void)
// {
// int i, j, t;
// for(i = 1;i < n - 1; i++) {
// printf("%d ", visit1[i]);
// }
// printf("%d\n", visit1[n - 1]);
// } int main(int argc, char const *argv[]) {
#ifndef _OJ_ //ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif int i, j;
Graph g;
g = creat_Graph();
for(i = 1; i <= g->nv; i++)
visit[i] = 0;
Topologicalsort(g); return 0;
}
输入:
6 7
1 2
2 3
1 5
2 4
3 6
5 4
4 6
输出:
i1 == 1
i1 == 2
i1 == 5
i1 == 3
i1 == 4
i1 == 6
-----------------------------------------------------------------------------------------------------------------------队列实现
---------------------------------------------------------------------------------------------------------------------------------------
//top 排序的实现 容器栈(正确) #include <cstdio>
#include <cstdlib>
//#define _OJ_
#define maxszie 100 int visit[100];
typedef struct stack1
{
int top;
int base;
int *elem;
} stack1, *stack; typedef struct Graph1
{
int nv;
int ne;
int G[100][100];
} Graph1, *Graph; stack
creat_stack(void)
{
stack s;
s = (stack) malloc (sizeof(stack1));
s->elem = (int*) malloc (sizeof(int) * maxszie);
s->top = s->base = 0;
return s;
} int
isempty(stack s)
{
if(s->top == s->base)
return 1;
else
return 0;
} void
push(stack s, int data)
{
s->elem[s->top++] = data;
} int
pop(stack s)
{
return s->elem[--s->top];
} Graph
creat_Graph(void)
{
int v1, v2, i, j;
Graph g;
g = (Graph) malloc (sizeof(Graph1));
scanf("%d %d", &(g->nv), &(g->ne));
for(i = 1;i <= g->nv; i++) {
for(j = 1;j <= g->nv; j++) {
g->G[i][j] = 0;
}
} for(i = 1;i <= g->ne; i++) {
scanf("%d %d", &v1, &v2);
g->G[v2][v1] = 1;
} return g;
} void
Topologicalsort(Graph g)
{
stack s;
int i, j, i1, cnt = 0;
int indegree[100];
s = creat_stack();
for(i = 1;i <= g->nv ; i++) {
indegree[i] = 0;
for(j = 1;j <= g->nv; j++) {
if(g->G[j][i] != 0) ++indegree[i];
}
if(indegree[i] == 0) {push(s, i); visit[i] = 1;}
} while (isempty(s) != 1) {
i1 = pop(s); printf("i1 == %d ", i1); cnt++;
for(i = 1;i <= g->nv; i++) {
if(g->G[i1][i] != 0) indegree[i]--;
if(indegree[i] == 0 && visit[i] == 0) {push(s, i); visit[i] = 1;}//printf("i2=%d\n", i);}
}
} if(cnt < g->nv) printf("error\n");
else printf("ok\n");
} int main(int argc, char const *argv[]) {
#ifndef _OJ_ //ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif int i;
Graph g;
g = creat_Graph();
for(i = 1; i <= g->nv; i++)
visit[i] = 0;
Topologicalsort(g); return 0;
}
-----------------------------------------------------------------------------------------------------------------------------
输入:
6 7
1 2
2 3
1 5
2 4
3 6
5 4
4 6
输出:
i1 == 6 i1 == 4 i1 == 5 i1 == 3 i1 == 2 i1 == 1 ok
-----------------------------------------------------------------------------------------------------------------------栈的实现
栈的实现和队列的实现其实是一样的,,不过一个是先进先出,,一个先进后出,,so答案有所出入,,不过原理都一样!!!
关于拓扑排序(topologicalsort)的更多相关文章
- 拓扑排序(TopologicalSort)算法
拓扑排序算法应用: 有些事情做都需要按照流程的去做,比如你准备约你小女友去影院看速度与激情7大片,首先你想的是我怎么到达影院,然后达到影院,你可以先买票,或者等小女友来了一起买票,然后一起进电影大厅. ...
- 【LeetCode】拓扑排序 topological-sort(共5题)
[207]Course Schedule [210]Course Schedule II [269]Alien Dictionary [329]Longest Increasing Path in a ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
- 拓扑排序(三)之 Java详解
前面分别介绍了拓扑排序的C和C++实现,本文通过Java实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处 ...
- 拓扑排序(二)之 C++详解
本章是通过C++实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处:http://www.cnblogs. ...
- POJ1094 拓扑排序
问题:POJ1094 本题考查拓扑排序算法 拓扑排序: 1)找到入度为0的点,加入已排序列表末尾: 2)删除该点,更新入度数组. 循环1)2)直到 1. 所有点都被删除,则找到一个拓扑 ...
- hdu4324 Triangle LOVE (拓扑排序)
这是一道最简单的拓扑排序题,好久没看这个算法了! 有点生疏了! 后附上百度的资料; #include<stdio.h> #include<string.h> int in[50 ...
- C++编程练习(12)----“有向图的拓扑排序“
设G={V,E}是一个具有 n 个顶点的有向图,V中的顶点序列 v1,v2,......,vn,满足若从顶点 vi 到 vj 有一条路径,则在顶点序列中顶点 vi 必在顶点 vj 之前.则称这样的顶点 ...
- 算法与数据结构(七) AOV网的拓扑排序(Swift版)
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
随机推荐
- asp.net 之 GC (垃圾回收机制)
今天抽时间好好整理了下GC相关知识,看了CSDN和博客园的几篇文章,有了一定的简单了解,决定根据个人理解整合一份随笔写下来,望诸位指教. 一:基础问题 1.首先需要知道了解什么是GC? GC如其名,就 ...
- cocos2dx屏幕适配方案
我们在利用cocos2dx来开发游戏时,在开始时就不可避免的会遇到屏幕适配问题,来使我们的游戏适应移动终端的各种分辨率大小.目前,大家采用的屏幕适配方案不一,网上的资料也比较丰富,下面我也将自己使用的 ...
- Archiving
There are typically four steps of archving: Preprocessing Write Store Delete Normally Store is inv ...
- 《搭建DNS负载均衡服务》RHEL6
搭建DNS负载均衡环境: 1.至少三台的linux虚拟机,一台主的DNS服务器,1台副的(可以N台),1台测试机. 负载均衡有很多种,apache那样的是为了缓解人们访问网站时给服务器造成太大的压力, ...
- Android开发之计算器(一)界面设计
计算器开发主要涉及到LinearLayout布局.EditText.Button的使用.为android入门基础内容. 打开android studio选择创建一个新的工程,应用程序的名称为Calcu ...
- 百度的domain命令到底有用吗?
曾几何时,站长和seoer们在百度输入domain:xxxxxxxx的时候弹出的结果数量让多少人兴奋和失落,为什么我们对百度的domain命令如此着迷呢?因为我们都认为百度的domain命令是查询网站 ...
- jquery如何通过name名称获取当前name的value值
本文为大家介绍下jquery通过name名称获取当前name的value值的具体实现,感兴趣的朋友可以参考下. 复制代码代码如下: $("*[name='name']").val( ...
- Z-BlogPHP 安装出现 (8) Undefined offset: 6 解决方法
有些cp面板的空间会在每个网页头部和页脚增加两个调用的文件,导致zblogPHP安装出错:(8) Undefined offset: 6 主要国外的主机中PHP配置文件两个选项auto_prepend ...
- PHP环境搭建(Windows8.1+IIS8.5+PHP5.6+PHPStorm)
第一次接触php是在2014-5月份左右,当时是自己的主攻方向是C#,对php比较排斥, 其中很多一部分原因,就是PHP的断点调试一直无法配置成功,用echo打印日志的方式排错,使得自己对php心生怨 ...
- Delphi XE5教程3:实例程序
内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者 ...