算法系列(十三)图论基本概念和拓扑排序
来源:互联网 发布:linux 进程启动时间 编辑:程序博客网 时间:2024/06/06 02:00
图的定义
一个图G=(V,E),由定点的集合V,和边的集合E组成。每一条边都是一副点对(v,w),边也称作弧,边上可以有权值。如果点对是有序的,那么图就是有向的。
图中的一条路径是一个顶点序列w1,w2,w3......wN,如果图中包含一条从顶点到自身的边,那么这个路径就是环。
有向无环图也成为DAG
如果在一个无向图中每个顶点到其它顶点都存在路径,则称这个无向图是连通的。具有这样性质的有向图被称为是强连通的。如果一个有向图不是强连通的,但是去掉方向后的基础图是连通的,那么该有向图称为是弱连通的。完全图是每一对顶点间都存在一条边的图。
进入一个顶点的边的个数称为该顶点的入度。每个有向无环图必定至少存在一个入度为0的顶点,至少存在一个出度为0的顶点,否则图中必然存在环。
图的表示
表示图的一种简单方法是使用一个二维数组,称为邻接矩阵。
如果图是稀疏的,更好的解决方法是使用邻接表。
拓扑排序
拓扑排序是对有向五环图的顶点排序,使得如果存在一条vi到vj的路径,那么在排序中vj在vi的后面。拓扑排序是不唯一的。
该DAG的拓扑序列为A B C D或者A C B D
拓扑排序的实现
先找出任意一个没有入边的顶点,然后显示该顶点,将它及其边删除,然后对图的其余部分做相同处理。
package com.algorithm.graphics;import java.util.Stack;import java.util.Vector;/** * 拓扑排序 * * @author chao * */public class TopSortGraph {int vertexNum;Vector[] vector;Stack stack;int[] result;int[] in;// 入度/** * * 构造一个图 * * @param num * 图的顶点数 * */public TopSortGraph(int num) {vertexNum = num;vector = new Vector[vertexNum];stack = new Stack();result = new int[vertexNum];in = new int[vertexNum];}/** * 向图中添加无向边 * * @param I * 边的一个顶点 * @param J * 边的另一个顶点 * @return 是否添加成功 */public boolean addEdge(int I, int J) {/** * 判断用户输入的是否是一个顶点,如果是,则返回flase,添加不成功 */if (J == I) {return false;}/** * 判断所输入的顶点值是否在图所顶点范围值内,如果不在,则提示顶点不存在 * */if (I < vertexNum && J < vertexNum && I >= 0 && J >= 0) {/** * * 判断边是否存在 */if (isEdgeExists(I, J)) {return false;}/** * 添加边,将孤头的入度加1 */vector[I].add(J);in[J]++;return true;}return false;}/** * 判断有向边是否存在 * * @param i * 要查询的有向边的一个孤尾 * @param j * 要查询的有向边的另一个孤头 * @return 边是否存在,false:不存在,true:存在 */public boolean isEdgeExists(int i, int j) {/** * 判断所输入的顶点值是否在图所顶点范围值内,如果不在,则提示顶点不存在 * */if (i < vertexNum && j < vertexNum && i >= 0 && j >= 0) {if (i == j) {return false;}/** * 判断i的邻接结点集是否为空 */if (vector[i] == null) {vector[i] = new Vector();}/** * 判断这条边是否存在,如果存在,则提示边已经存在 */for (int q = 0; q < vector[i].size(); q++) {if (((Integer) vector[i].get(q)).intValue() == j) {System.out.println("顶点" + i + "和" + "顶点" + j + "这两点之间存在边");return true;}}}return false;}/** * 拓扑排序 */public void TopSort() {for (int i = 0; i < vertexNum; i++)if (in[i] == 0)stack.push(i);int k = 0;while (!stack.isEmpty()) {result[k] = (Integer) stack.pop();if (vector[result[k]] != null) {for (int j = 0; j < vector[result[k]].size(); j++) {int temp = (Integer) vector[result[k]].get(j);if (--in[temp] == 0) {stack.push(temp);}}}k++;}if (k < vertexNum) {System.out.println("有回路");System.exit(0);}}/** * 拓扑结果 * * @return */public int[] getResult() {return result;}}
代码实现可以看github,地址https://github.com/robertjc/simplealgorithm
github代码也在不断完善中,有些地方可能有问题,还请多指教
欢迎扫描二维码,关注公众号
0 0
- 算法系列(十三)图论基本概念和拓扑排序
- (十三周项目5)拓扑排序算法验证
- 基础算法系列(十三)排序算法之地精排序
- 十三周 项目一 运行所讲算法,观察结果并领会算法(拓扑排序)
- 图算法:拓扑排序
- 十三周 项目5-拓扑排序算法验证
- 算法系列笔记7(有关图的算法一—搜索,拓扑排序和强连通分支)
- 算法系列笔记7(有关图的算法一—搜索,拓扑排序和强连通分支)
- 图论算法:拓扑排序(Topological Sort)
- 图论算法——拓扑排序
- 图论入门:拓扑排序算法
- 图之Prim算法、kruskal算法和拓扑排序
- 图算法之拓扑排序
- 图算法之拓扑排序
- 图算法之拓扑排序
- 算法(十一)拓扑排序
- 数据结构-----图的拓扑排序和关键路径算法
- 图算法 图的表示(邻接表和邻接矩阵)和拓扑排序
- ERROR:transport error 202: gethostbyname: unknown host
- 深入JVM锁机制-synchronized
- 操作xml文档的通用方法
- Exception in thread “commons-pool-EvictionTimer”
- 用文件函数获取文件的大小代码片段
- 算法系列(十三)图论基本概念和拓扑排序
- HYSBZ 1036 树链剖分
- hdu2087
- jsp与servlet传值相关问题
- 【剑指offer】二叉搜索树与双向链表
- Rabbitmq 学习笔记(二)队列
- C2. Brain Network (medium)
- use delegate to update UI
- Wooden Sticks(贪心)