当前位置:   article > 正文

拓扑排序的算法实现_如何实现拓扑排序算法

如何实现拓扑排序算法

一、定义

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序

二、DFS算法

找出一个入度为 0 的顶点,通过递归的方式遍历它所有可达的顶点,将其输出到拓扑排序的结果序列中,对遍历过的顶点做标记,避免其被重复访问。循环执行上面的过程,直到所有的顶点都被输出。

1.基于邻接表实现

  1. public class TopologicalSort_AdjacencyList_Dfs {
  2. private int mVertexNum; // 顶点数
  3. private int[] mInDegree; // 顶点入度数
  4. private List<Integer> mAdjacencyList[]; // 邻接表
  5. private boolean[] isVisited; // 用来避免顶点被重复访问
  6. private Stack<Integer> mReversePost; // 用栈来保存排序结果
  7. public TopologicalSort_AdjacencyList_Dfs(int vertexNum) {
  8. this.mVertexNum = vertexNum;
  9. this.mInDegree = new int[vertexNum];
  10. this.mAdjacencyList = new LinkedList[vertexNum];
  11. for (int i = 0; i < vertexNum; ++i) {
  12. mAdjacencyList[i] = new LinkedList<>();
  13. }
  14. this.isVisited = new boolean[vertexNum];
  15. this.mReversePost = new Stack<>();
  16. }
  17. /**
  18. * 添加图的边,累计终止顶点入度
  19. *
  20. * @param s 起始顶点
  21. * @param t 终止顶点
  22. */
  23. public void addEdge(int s, int t) {
  24. mAdjacencyList[s].add(t);
  25. mInDegree[t]++;
  26. }
  27. /**
  28. * 拓扑排序
  29. */
  30. public void sort() {
  31. for (int i = 0; i < mVertexNum; i++) {
  32. if (mInDegree[i] == 0) {
  33. recurDfs(i);
  34. }
  35. }
  36. System.out.println(mReversePost);
  37. }
  38. /**
  39. * 递归方法
  40. *
  41. * @param s
  42. */
  43. private void recurDfs(int s) {
  44. if (isVisited[s] || mReversePost.size() == mVertexNum) {
  45. return;
  46. }
  47. isVisited[s] = true;
  48. mReversePost.push(s);
  49. for (int i = 0; i < mAdjacencyList[s].size(); i++) {
  50. int w = mAdjacencyList[s].get(i);
  51. if (isVisited[w]) {
  52. return;
  53. }
  54. mInDegree[w]--;
  55. if (mInDegree[w] == 0) {
  56. recurDfs(w);
  57. }
  58. }
  59. }
  60. public static void main(String[] args) {
  61. TopologicalSort_AdjacencyList_Dfs graph = new TopologicalSort_AdjacencyList_Dfs(8);
  62. graph.addEdge(0, 1);
  63. graph.addEdge(0, 3);
  64. // graph.addEdge(1, 2);
  65. graph.addEdge(1, 4);
  66. graph.addEdge(2, 5);
  67. graph.addEdge(4, 5);
  68. graph.addEdge(4, 6);
  69. graph.addEdge(5, 7);
  70. graph.addEdge(6, 7);
  71. graph.sort();
  72. }
  73. }

2.基于邻接矩阵实现

  1. public class TopologicalSort_AdjacencyMatrix_Dfs {
  2. private int mVertexNum; // 顶点数
  3. private int[] mInDegree; // 顶点入度数
  4. private int[][] mAdjacencyMatrix; // 邻接矩阵
  5. private boolean[] isVisited; // 用来避免顶点被重复访问
  6. private Stack<Integer> mReversePost; // 用栈来保存排序结果
  7. public TopologicalSort_AdjacencyMatrix_Dfs(int vertexNum) {
  8. this.mVertexNum = vertexNum;
  9. this.mInDegree = new int[vertexNum];
  10. this.mAdjacencyMatrix = new int[vertexNum][vertexNum];
  11. for (int i = 0; i < vertexNum; i++) {
  12. for (int j = 0; j < vertexNum; j++) {
  13. mAdjacencyMatrix[i][j] = 0;
  14. }
  15. }
  16. this.isVisited = new boolean[vertexNum];
  17. this.mReversePost = new Stack<>();
  18. }
  19. /**
  20. * 添加图的边,累计终止顶点入度
  21. *
  22. * @param s 起始顶点
  23. * @param t 终止顶点
  24. */
  25. public void addEdge(int s, int t) {
  26. mAdjacencyMatrix[s][t] = 1;
  27. mInDegree[t]++;
  28. }
  29. /**
  30. * 拓扑排序
  31. */
  32. public void sort() {
  33. for (int i = 0; i < mVertexNum; i++) {
  34. if (mInDegree[i] == 0) {
  35. recurDfs(i);
  36. }
  37. }
  38. System.out.println(mReversePost);
  39. }
  40. /**
  41. * 递归方法
  42. *
  43. * @param s
  44. */
  45. private void recurDfs(int s) {
  46. if (isVisited[s] || mReversePost.size() == mVertexNum) {
  47. return;
  48. }
  49. isVisited[s] = true;
  50. mReversePost.push(s);
  51. for (int i = 0; i < mVertexNum; i++) {
  52. if (mAdjacencyMatrix[s][i] == 1 && !isVisited[i]) {
  53. mInDegree[i]--;
  54. if (mInDegree[i] == 0) {
  55. recurDfs(i);
  56. }
  57. }
  58. }
  59. }
  60. public static void main(String[] args) {
  61. TopologicalSort_AdjacencyMatrix_Dfs graph = new TopologicalSort_AdjacencyMatrix_Dfs(8);
  62. graph.addEdge(0, 1);
  63. graph.addEdge(0, 3);
  64. // graph.addEdge(1, 2);
  65. graph.addEdge(1, 4);
  66. graph.addEdge(2, 5);
  67. graph.addEdge(4, 5);
  68. graph.addEdge(4, 6);
  69. graph.addEdge(5, 7);
  70. graph.addEdge(6, 7);
  71. graph.sort();
  72. }
  73. }

三、Kahn算法

找出一个入度为 0 的顶点,将其输出到拓扑排序的结果序列中,并且把这个顶点从图中删除。循环执行上面的过程,直到所有的顶点都被输出。

1.基于邻接表实现

  1. public class TopologicalSort_AdjacencyList_Kahn {
  2. private int mVertexNum; // 顶点数
  3. private int[] mInDegree; // 顶点入度数
  4. private List<Integer> mAdjacencyList[]; // 邻接表
  5. private Deque<Integer> mZeroDegreeDeque; // 入度数为0的顶点
  6. public TopologicalSort_AdjacencyList_Kahn(int vertexNum) {
  7. this.mVertexNum = vertexNum;
  8. this.mInDegree = new int[vertexNum];
  9. this.mAdjacencyList = new LinkedList[vertexNum];
  10. for (int i = 0; i < vertexNum; ++i) {
  11. mAdjacencyList[i] = new LinkedList<>();
  12. }
  13. this.mZeroDegreeDeque = new ArrayDeque<>();
  14. }
  15. /**
  16. * 添加图的边,累计终止顶点入度
  17. *
  18. * @param s 起始顶点
  19. * @param t 终止顶点
  20. */
  21. public void addEdge(int s, int t) {
  22. mAdjacencyList[s].add(t);
  23. mInDegree[t]++;
  24. }
  25. /**
  26. * 拓扑排序
  27. */
  28. public void sort() {
  29. for (int i = 0; i < mVertexNum; i++) {
  30. if (mInDegree[i] == 0) {
  31. mZeroDegreeDeque.offer(i);
  32. }
  33. }
  34. List<Integer> result = new ArrayList<>();
  35. while (!mZeroDegreeDeque.isEmpty()) {
  36. int s = mZeroDegreeDeque.poll();
  37. for (int j = 0; j < mAdjacencyList[s].size(); j++) {
  38. int w = mAdjacencyList[s].get(j);
  39. mInDegree[w]--;
  40. if (mInDegree[w] == 0) {
  41. mZeroDegreeDeque.offer(w);
  42. }
  43. }
  44. result.add(s);
  45. }
  46. System.out.println(result);
  47. }
  48. public static void main(String[] args) {
  49. TopologicalSort_AdjacencyList_Kahn graph = new TopologicalSort_AdjacencyList_Kahn(8);
  50. graph.addEdge(0, 1);
  51. graph.addEdge(0, 3);
  52. graph.addEdge(1, 2);
  53. graph.addEdge(1, 4);
  54. graph.addEdge(2, 5);
  55. graph.addEdge(4, 5);
  56. graph.addEdge(4, 6);
  57. graph.addEdge(5, 7);
  58. graph.addEdge(6, 7);
  59. graph.sort();
  60. }
  61. }

2.基于邻接矩阵实现

  1. public class TopologicalSort_AdjacencyMatrix_Kahn {
  2. private int mVertexNum; // 顶点数
  3. private int[] mInDegree; // 顶点入度数
  4. private int[][] mAdjacencyMatrix; // 邻接矩阵
  5. private Deque<Integer> mZeroDegreeDeque; // 入度数为0的顶点
  6. public TopologicalSort_AdjacencyMatrix_Kahn(int vertexNum) {
  7. this.mVertexNum = vertexNum;
  8. this.mInDegree = new int[vertexNum];
  9. this.mAdjacencyMatrix = new int[vertexNum][vertexNum];
  10. for (int i = 0; i < vertexNum; i++) {
  11. for (int j = 0; j < vertexNum; j++) {
  12. mAdjacencyMatrix[i][j] = 0;
  13. }
  14. }
  15. this.mZeroDegreeDeque = new ArrayDeque<>();
  16. }
  17. /**
  18. * 添加图的边,累计终止顶点入度
  19. *
  20. * @param s 起始顶点
  21. * @param t 终止顶点
  22. */
  23. public void addEdge(int s, int t) {
  24. mAdjacencyMatrix[s][t] = 1;
  25. mInDegree[t]++;
  26. }
  27. /**
  28. * 拓扑排序
  29. */
  30. public void sort() {
  31. for (int i = 0; i < mVertexNum; i++) {
  32. if (mInDegree[i] == 0) {
  33. mZeroDegreeDeque.offer(i);
  34. }
  35. }
  36. List<Integer> result = new ArrayList<>();
  37. while (!mZeroDegreeDeque.isEmpty()) {
  38. int s = mZeroDegreeDeque.poll();
  39. for (int j = 0; j < mVertexNum; j++) {
  40. if (mAdjacencyMatrix[s][j] != 1) {
  41. continue;
  42. }
  43. mInDegree[j]--;
  44. if (mInDegree[j] == 0) {
  45. mZeroDegreeDeque.offer(j);
  46. }
  47. }
  48. result.add(s);
  49. }
  50. System.out.println(result);
  51. }
  52. public static void main(String[] args) {
  53. TopologicalSort_AdjacencyMatrix_Kahn graph = new TopologicalSort_AdjacencyMatrix_Kahn(8);
  54. graph.addEdge(0, 1);
  55. graph.addEdge(0, 3);
  56. graph.addEdge(1, 2);
  57. graph.addEdge(1, 4);
  58. graph.addEdge(2, 5);
  59. graph.addEdge(4, 5);
  60. graph.addEdge(4, 6);
  61. graph.addEdge(5, 7);
  62. graph.addEdge(6, 7);
  63. graph.sort();
  64. }
  65. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/870789
推荐阅读
相关标签
  

闽ICP备14008679号