赞
踩
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
找出一个入度为 0 的顶点,通过递归的方式遍历它所有可达的顶点,将其输出到拓扑排序的结果序列中,对遍历过的顶点做标记,避免其被重复访问。循环执行上面的过程,直到所有的顶点都被输出。
- public class TopologicalSort_AdjacencyList_Dfs {
-
- private int mVertexNum; // 顶点数
- private int[] mInDegree; // 顶点入度数
- private List<Integer> mAdjacencyList[]; // 邻接表
-
- private boolean[] isVisited; // 用来避免顶点被重复访问
- private Stack<Integer> mReversePost; // 用栈来保存排序结果
-
- public TopologicalSort_AdjacencyList_Dfs(int vertexNum) {
- this.mVertexNum = vertexNum;
- this.mInDegree = new int[vertexNum];
- this.mAdjacencyList = new LinkedList[vertexNum];
- for (int i = 0; i < vertexNum; ++i) {
- mAdjacencyList[i] = new LinkedList<>();
- }
- this.isVisited = new boolean[vertexNum];
- this.mReversePost = new Stack<>();
- }
-
- /**
- * 添加图的边,累计终止顶点入度
- *
- * @param s 起始顶点
- * @param t 终止顶点
- */
- public void addEdge(int s, int t) {
- mAdjacencyList[s].add(t);
- mInDegree[t]++;
- }
-
- /**
- * 拓扑排序
- */
- public void sort() {
- for (int i = 0; i < mVertexNum; i++) {
- if (mInDegree[i] == 0) {
- recurDfs(i);
- }
- }
-
- System.out.println(mReversePost);
- }
-
- /**
- * 递归方法
- *
- * @param s
- */
- private void recurDfs(int s) {
- if (isVisited[s] || mReversePost.size() == mVertexNum) {
- return;
- }
-
- isVisited[s] = true;
- mReversePost.push(s);
-
- for (int i = 0; i < mAdjacencyList[s].size(); i++) {
- int w = mAdjacencyList[s].get(i);
- if (isVisited[w]) {
- return;
- }
-
- mInDegree[w]--;
- if (mInDegree[w] == 0) {
- recurDfs(w);
- }
- }
- }
-
- public static void main(String[] args) {
- TopologicalSort_AdjacencyList_Dfs graph = new TopologicalSort_AdjacencyList_Dfs(8);
- graph.addEdge(0, 1);
- graph.addEdge(0, 3);
- // graph.addEdge(1, 2);
- graph.addEdge(1, 4);
- graph.addEdge(2, 5);
- graph.addEdge(4, 5);
- graph.addEdge(4, 6);
- graph.addEdge(5, 7);
- graph.addEdge(6, 7);
- graph.sort();
- }
- }
- public class TopologicalSort_AdjacencyMatrix_Dfs {
-
- private int mVertexNum; // 顶点数
- private int[] mInDegree; // 顶点入度数
- private int[][] mAdjacencyMatrix; // 邻接矩阵
-
- private boolean[] isVisited; // 用来避免顶点被重复访问
- private Stack<Integer> mReversePost; // 用栈来保存排序结果
-
- public TopologicalSort_AdjacencyMatrix_Dfs(int vertexNum) {
- this.mVertexNum = vertexNum;
- this.mInDegree = new int[vertexNum];
- this.mAdjacencyMatrix = new int[vertexNum][vertexNum];
- for (int i = 0; i < vertexNum; i++) {
- for (int j = 0; j < vertexNum; j++) {
- mAdjacencyMatrix[i][j] = 0;
- }
- }
- this.isVisited = new boolean[vertexNum];
- this.mReversePost = new Stack<>();
- }
-
- /**
- * 添加图的边,累计终止顶点入度
- *
- * @param s 起始顶点
- * @param t 终止顶点
- */
- public void addEdge(int s, int t) {
- mAdjacencyMatrix[s][t] = 1;
- mInDegree[t]++;
- }
-
- /**
- * 拓扑排序
- */
- public void sort() {
- for (int i = 0; i < mVertexNum; i++) {
- if (mInDegree[i] == 0) {
- recurDfs(i);
- }
- }
-
- System.out.println(mReversePost);
- }
-
- /**
- * 递归方法
- *
- * @param s
- */
- private void recurDfs(int s) {
- if (isVisited[s] || mReversePost.size() == mVertexNum) {
- return;
- }
-
- isVisited[s] = true;
- mReversePost.push(s);
-
- for (int i = 0; i < mVertexNum; i++) {
- if (mAdjacencyMatrix[s][i] == 1 && !isVisited[i]) {
- mInDegree[i]--;
- if (mInDegree[i] == 0) {
- recurDfs(i);
- }
- }
- }
- }
-
- public static void main(String[] args) {
- TopologicalSort_AdjacencyMatrix_Dfs graph = new TopologicalSort_AdjacencyMatrix_Dfs(8);
- graph.addEdge(0, 1);
- graph.addEdge(0, 3);
- // graph.addEdge(1, 2);
- graph.addEdge(1, 4);
- graph.addEdge(2, 5);
- graph.addEdge(4, 5);
- graph.addEdge(4, 6);
- graph.addEdge(5, 7);
- graph.addEdge(6, 7);
- graph.sort();
- }
- }
找出一个入度为 0 的顶点,将其输出到拓扑排序的结果序列中,并且把这个顶点从图中删除。循环执行上面的过程,直到所有的顶点都被输出。
- public class TopologicalSort_AdjacencyList_Kahn {
-
- private int mVertexNum; // 顶点数
- private int[] mInDegree; // 顶点入度数
- private List<Integer> mAdjacencyList[]; // 邻接表
- private Deque<Integer> mZeroDegreeDeque; // 入度数为0的顶点
-
- public TopologicalSort_AdjacencyList_Kahn(int vertexNum) {
- this.mVertexNum = vertexNum;
- this.mInDegree = new int[vertexNum];
- this.mAdjacencyList = new LinkedList[vertexNum];
- for (int i = 0; i < vertexNum; ++i) {
- mAdjacencyList[i] = new LinkedList<>();
- }
- this.mZeroDegreeDeque = new ArrayDeque<>();
- }
-
- /**
- * 添加图的边,累计终止顶点入度
- *
- * @param s 起始顶点
- * @param t 终止顶点
- */
- public void addEdge(int s, int t) {
- mAdjacencyList[s].add(t);
- mInDegree[t]++;
- }
-
- /**
- * 拓扑排序
- */
- public void sort() {
- for (int i = 0; i < mVertexNum; i++) {
- if (mInDegree[i] == 0) {
- mZeroDegreeDeque.offer(i);
- }
- }
-
- List<Integer> result = new ArrayList<>();
-
- while (!mZeroDegreeDeque.isEmpty()) {
- int s = mZeroDegreeDeque.poll();
- for (int j = 0; j < mAdjacencyList[s].size(); j++) {
- int w = mAdjacencyList[s].get(j);
- mInDegree[w]--;
- if (mInDegree[w] == 0) {
- mZeroDegreeDeque.offer(w);
- }
- }
- result.add(s);
- }
-
- System.out.println(result);
- }
-
- public static void main(String[] args) {
- TopologicalSort_AdjacencyList_Kahn graph = new TopologicalSort_AdjacencyList_Kahn(8);
- graph.addEdge(0, 1);
- graph.addEdge(0, 3);
- graph.addEdge(1, 2);
- graph.addEdge(1, 4);
- graph.addEdge(2, 5);
- graph.addEdge(4, 5);
- graph.addEdge(4, 6);
- graph.addEdge(5, 7);
- graph.addEdge(6, 7);
- graph.sort();
- }
- }
- public class TopologicalSort_AdjacencyMatrix_Kahn {
-
- private int mVertexNum; // 顶点数
- private int[] mInDegree; // 顶点入度数
- private int[][] mAdjacencyMatrix; // 邻接矩阵
- private Deque<Integer> mZeroDegreeDeque; // 入度数为0的顶点
-
- public TopologicalSort_AdjacencyMatrix_Kahn(int vertexNum) {
- this.mVertexNum = vertexNum;
- this.mInDegree = new int[vertexNum];
- this.mAdjacencyMatrix = new int[vertexNum][vertexNum];
- for (int i = 0; i < vertexNum; i++) {
- for (int j = 0; j < vertexNum; j++) {
- mAdjacencyMatrix[i][j] = 0;
- }
- }
- this.mZeroDegreeDeque = new ArrayDeque<>();
- }
-
- /**
- * 添加图的边,累计终止顶点入度
- *
- * @param s 起始顶点
- * @param t 终止顶点
- */
- public void addEdge(int s, int t) {
- mAdjacencyMatrix[s][t] = 1;
- mInDegree[t]++;
- }
-
- /**
- * 拓扑排序
- */
- public void sort() {
- for (int i = 0; i < mVertexNum; i++) {
- if (mInDegree[i] == 0) {
- mZeroDegreeDeque.offer(i);
- }
- }
-
- List<Integer> result = new ArrayList<>();
-
- while (!mZeroDegreeDeque.isEmpty()) {
- int s = mZeroDegreeDeque.poll();
- for (int j = 0; j < mVertexNum; j++) {
- if (mAdjacencyMatrix[s][j] != 1) {
- continue;
- }
-
- mInDegree[j]--;
- if (mInDegree[j] == 0) {
- mZeroDegreeDeque.offer(j);
- }
- }
- result.add(s);
- }
-
- System.out.println(result);
- }
-
- public static void main(String[] args) {
- TopologicalSort_AdjacencyMatrix_Kahn graph = new TopologicalSort_AdjacencyMatrix_Kahn(8);
- graph.addEdge(0, 1);
- graph.addEdge(0, 3);
- graph.addEdge(1, 2);
- graph.addEdge(1, 4);
- graph.addEdge(2, 5);
- graph.addEdge(4, 5);
- graph.addEdge(4, 6);
- graph.addEdge(5, 7);
- graph.addEdge(6, 7);
- graph.sort();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。