数据结构3-拓扑排序
来源:互联网 发布:汉仪菱心简体mac版 编辑:程序博客网 时间:2024/06/08 18:09
1.拓扑排序的理解
拓扑排序是用于有向、无环图里,将优先的节点先输出的一种排序方式。有向是指节点与节点之间有一个优先关系,例如想烧一壶水,那么必须先用水壶去接水,再用水壶去烧水,其中接水就是烧水的优先动作,想烧水就必须先接水。无环是指一系列的动作中必须是有一个入口和一个出口的,举一个有环的例子,先有鸡还是先有蛋,鸡要蛋孵,蛋要鸡下(不从科学角度考虑,例子的设定就是这样),这个例子中就出现了有环的现象,鸡和蛋之前互为优先关系,有环的图是无法进行拓扑排序的。
2.偏序和全序
只要是满足了有向、无环的图就满足偏序关系。那么如果要满足全序就得多加一个条件,有向、无环图中任意两顶点之间还需要有明确的关系。先说一个偏序的例子,小明有买菜和炒菜两件事要做,买菜的顺序是先到菜市场,再买菜,最后回家;炒菜的顺序是先到冰箱拿菜出来,再洗菜,最后炒菜。在这两件事情中不分先后,那么就可能会出现两种情况,先买菜后炒菜或者先炒菜后买菜,这就是偏序。如果是全序的情况下这个例子就会增加一个新的条件,小明的冰箱里没有菜了,他需要先去买菜之后才可以炒菜,这样出现的情况就只有一种情况,这就是全序。
3.算法思路
(1)找到一个没有后继的定点存放到栈中(得到一个倒序的顺序)
(2)从图中删除该定点和它的弧(与其他定点的关系)
(3)出栈(得到正序的拓扑排序结果)
4.代码
/*拓扑排序算法*//// <summary>/// 寻找没有后继点的节点(出度为0)/// 邻接矩阵的一行全为0/// </summary>/// <returns></returns>private int FindNoSuccessor(){ bool isEdge; for (int i = 0; i < numVert; i++) //numVert是图中的顶点数 { isEdge = false; for (int j = 0; j < numVert; j++) { if (adjmatrix[i, j] != 0) { isEdge = true; break; } } if (!isEdge) return i; } return -1;}/// <summary>/// 从顶点数组中删除点/// 从临接矩阵中删除点/// </summary>/// <param name="vert"></param>private void DelVertex(int vert){ if (vert <= numVert - 1) { //从顶点数组中删除点 for (int i = vert; i < numVert; i++) { vertices[i] = vertices[i + 1]; //vertices是用于存储图的数组 } //从临接矩阵中删除点 //删除行 for (int i = vert; i < numVert; i++) { MoveRow(i, numVert); } //删除列 for (int i = vert; i < numVert; i++) { MoveCol(i, numVert - 1); } numVert--; }}/// <summary>/// 移动临接矩阵中的行/// </summary>/// <param name="row"></param>/// <param name="lenth"></param>private void MoveRow(int row, int lenth){ for (int col = row; col < lenth; col++) { adjmatrix[row, col] = adjmatrix[row + 1, col]; //adjmatrix是用于存放定点间关系的矩阵(临接矩阵) }}/// <summary>/// 移动列/// </summary>/// <param name="col"></param>/// <param name="lenth"></param>private void MoveCol(int col, int lenth){ for (int row = col; row < lenth; row++) { adjmatrix[row, col] = adjmatrix[row, col + 1]; }}/// <summary>/// 拓扑排序/// 将出度为0的节点入栈,这样就可以把拓扑排序的顺序从后往前保存起来,/// 再从栈里取出,顺序就是从前往后的。/// </summary>public void TopSort(){ int origVerts = numVert; //存放返回节点的栈 System.Collections.Stack result = new Stack(); while (numVert > 0) { //找到第一个没有后继节点的节点 int currVertex = FindNoSuccessor(); if (currVertex == -1) { Console.WriteLine("图为环路图,不能搞拓扑排序"); return; } //如果找到,将其加入返回结果栈 result.Push(vertices[currVertex].Data); //然后删除此节点 DelVertex(currVertex); } /*输出排序后的结果*/ Console.Write("拓扑排序的顺序为:"); while (result.Count > 0) { Console.Write(result.Pop() + " "); } Console.WriteLine();}
阅读全文
0 0
- 数据结构3-拓扑排序
- 数据结构--拓扑排序
- 【数据结构】拓扑排序_TopologicalSort
- 数据结构-拓扑排序
- 数据结构:图--拓扑排序
- 数据结构:图--拓扑排序
- 数据结构之拓扑排序
- 【数据结构】拓扑排序算法
- 数据结构--拓扑排序
- 数据结构 - 拓扑排序
- 数据结构之拓扑排序
- java数据结构 拓扑排序
- 数据结构之拓扑排序
- 【数据结构】拓扑排序
- 数据结构之拓扑排序
- 数据结构之拓扑排序
- 数据结构--拓扑排序算法
- 数据结构---拓扑排序详解
- CET 4词汇
- 欢迎使用CSDN-markdown编辑器
- Swift:"奇怪"的事件响应链
- bz入门oj 1457: 最大全零矩形
- python 爬虫爬取所有上市公司公告信息(四)
- 数据结构3-拓扑排序
- 欢迎使用CSDN-markdown编辑器
- 18:肿瘤面积
- 获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列。
- Stream API
- Apache Thrift基于RPC的远程调用 c++
- JS中的call和apply
- 组合数的两种计算方法(递推,对数)
- 安装的python导入arcpy