标签:
一个图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; } }
欢迎扫描二维码,关注公众号
标签:
原文地址:http://blog.csdn.net/robertcpp/article/details/51879346