图的遍历(深度遍历和广度遍历)

  
  
  1. /**
  2. * 图的遍历方式:深度优先遍历和广度优先遍历-》先创建图的邻接矩阵,求出某个顶点的第一个链接顶点-》如果某个顶点有好多个连通的顶点,求与之连通的第2个顶点的下一个顶点的位置
  3. * -》深度优先遍历:先遍历某个顶点的第一个连通的顶点-》迭代的方式找到改顶点的下个第一个顶点
  4. *
  5. * @author timmy1
  6. *
  7. */
  8. public class GraphTraverse {
  9. int[][] matrix;// 矩阵
  10. int MAX_WEIGHT = Integer.MAX_VALUE;
  11. int size;// 顶点个数
  12. boolean[] isVisted;// 标示顶点是否被访问过
  13. private void createGraph(int index) {
  14. size = index;
  15. matrix = new int[index][index];
  16. int[] a0 = { 0, 10, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
  17. int[] a1 = { 10, 0, 18, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, MAX_WEIGHT, 12 };
  18. int[] a2 = { MAX_WEIGHT, MAX_WEIGHT, 0, 22, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 8 };
  19. int[] a3 = { MAX_WEIGHT, MAX_WEIGHT, 22, 0, 20, MAX_WEIGHT, 24, 16, 21 };
  20. int[] a4 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 20, 0, 26, MAX_WEIGHT, 7, MAX_WEIGHT };
  21. int[] a5 = { 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 26, 0, 17, MAX_WEIGHT, MAX_WEIGHT };
  22. int[] a6 = { MAX_WEIGHT, 16, MAX_WEIGHT, 24, MAX_WEIGHT, 17, 0, 19, MAX_WEIGHT };
  23. int[] a7 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, 7, MAX_WEIGHT, 19, 0, MAX_WEIGHT };
  24. int[] a8 = { MAX_WEIGHT, 12, 8, 21, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 0 };
  25. matrix[0] = a0;
  26. matrix[1] = a1;
  27. matrix[2] = a2;
  28. matrix[3] = a3;
  29. matrix[4] = a4;
  30. matrix[5] = a5;
  31. matrix[6] = a6;
  32. matrix[7] = a7;
  33. matrix[8] = a8;
  34. }
  35. // 深度优先遍历
  36. public void DFS() {
  37. isVisted = new boolean[size];
  38. for (int j = 0; j < size; j++) {
  39. if (!isVisted[j]) {
  40. PrintUtil.print("访问到第:" + j + "顶点");
  41. depthFirstSearch(j);
  42. }
  43. }
  44. }
  45. /**
  46. * 图的深度优先算法实现
  47. *
  48. * @param i
  49. * 标示第几个顶点
  50. */
  51. private void depthFirstSearch(int i) {
  52. isVisted[i] = true;
  53. // 先找到改顶点的第一个连通顶点下标
  54. int vertex = getFirstVertex(i);
  55. while (vertex != -1) {// 存在第一个连通的顶点-》是否已经访问过->没有访问过-》访问-》再以该新顶点深度遍历
  56. if (!isVisted[vertex]) {
  57. isVisted[vertex] = true;
  58. PrintUtil.print("访问到第:" + vertex + "顶点");
  59. depthFirstSearch(vertex);
  60. }
  61. vertex = getNextVertex(i, vertex);
  62. }
  63. }
  64. //广度优先遍历
  65. private void BFS() {
  66. isVisted = new boolean[size];
  67. for (int j = 0; j < size; j++) {
  68. if (!isVisted[j]) {
  69. PrintUtil.print("访问到第:" + j + "顶点");
  70. broadFirstSearch(j);
  71. }
  72. }
  73. }
  74. /**
  75. * 图的广度优先遍历实现:采用队列进行辅助,使用队列的增加和删除元素的方法-》实现思路为:先获取到某个顶点,-》该顶点第一个顶点-》第一个顶点后的顶点
  76. * @param j
  77. */
  78. private void broadFirstSearch(int j) {
  79. int firstVertex;
  80. LinkedList<Integer> list = new LinkedList<Integer>();
  81. isVisted[j] = true;
  82. list.add(j);
  83. while(!list.isEmpty()){
  84. int vertex = list.removeFirst();//前面保存的顶点
  85. firstVertex = getFirstVertex(vertex);//第一个顶点
  86. while(firstVertex != -1){
  87. if(!isVisted[firstVertex]){
  88. isVisted[firstVertex] = true;
  89. PrintUtil.print("访问到第:" + firstVertex+ "顶点");
  90. list.add(firstVertex);
  91. }
  92. //拿到下一个顶点->赋值
  93. firstVertex = getNextVertex(vertex, firstVertex);
  94. }
  95. }
  96. }
  97. /**
  98. * 找到顶点i的第一个连通的顶点
  99. *
  100. * @param i
  101. * @return 顶点下标,-1表示该顶点没有与之连通的顶点
  102. */
  103. private int getFirstVertex(int i) {
  104. for (int j = 0; j < size; j++) {
  105. if (matrix[i][j] > 0 && matrix[i][j] < MAX_WEIGHT) {
  106. return j;
  107. }
  108. }
  109. return -1;
  110. }
  111. /**
  112. * 求顶点base,第index顶点后的下一个顶点
  113. *
  114. * @param base
  115. * @param index
  116. * @return
  117. */
  118. private int getNextVertex(int base, int index) {
  119. for (int j = index + 1; j < size; j++) {
  120. if (matrix[base][j] > 0 && matrix[base][j] < MAX_WEIGHT) {
  121. return j;
  122. }
  123. }
  124. return -1;
  125. }
  126. public static void main(String[] args) {
  127. GraphTraverse graph = new GraphTraverse();
  128. graph.createGraph(9);
  129. // graph.DFS();
  130. graph.BFS();
  131. }
  132. }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值