关于拓扑排序(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网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
随机推荐
- 设置ORACLE数据库游标大小
先用超级管理员(sys)登陆服务器: sqlplus "sys/***@orcl as sysdba" 连接到:Oracle 查看ORACLE最大游标数: SQL> show ...
- Java之简单图形面积计算
设计一个类层次,定义一个抽象类--形状(类名:shape).其中包括求形状的面积抽象方法(方法名:calArea()).继承该抽象类定义三角形(Triangle).矩形(Rectangle).圆(Ci ...
- 你所不知道的html5与html中的那些事第三篇
文章简介: 关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后,所有的工作 ...
- c#与java之比较(转自Jack.Wang's home)
很多人说C#是微软用来和Java抗衡的武器,因为二者在很大程度上有着惊人的相似 ,尽管如此,两者不同的地方也很多,所谓“于细微处见差异”.那么两者的相似和区 别都在什么地方呢?我们从今天开始,会从各个 ...
- Jquery 学习二
一.事件编程 1.基本事件(以方法形式存在的) 基本语法: 原生Javascript代码中的事件绑定方式: DOM对象.事件 = 事件的处理程序 jQuery代码中的事件绑定方式: jQuery对 ...
- 项目中Service层的写法
截取自项目中的一个service实现类,记录一下: base类 package com.bupt.auth.service.base; import javax.annotation.Resource ...
- java利用反射绕过私有检查机制实行对private、protected成员变量或方法的访问
在java中,如果类里面的变量是声明了private的,那么只能在被类中访问,外界不能调用,如果是protected类型的,只能在子类或本包中调用,俗话说没有不透风的墙.但是可以利用java中的反射从 ...
- springmvc 精华
Spring Mvc简介: Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求 ...
- wage
#include<iostream> using namespace std; int main() { double wage1,wage2,time; cout<<&quo ...
- VKP5 Price Calculation – List Variant & KZPBL (Delete site level)
List Variant: Configuration in Logistic General –> Retail Pricing –> Sales Price Calculation – ...