日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

树-广度优先和深度优先搜索算法

發布時間:2023/12/31 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树-广度优先和深度优先搜索算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

廣度優先和深度優先搜索算法

本章主要講述廣度優先搜索算法BFS(Breadth First Search)和深度優先算法DFS(Depth First Search)。

  • 廣度優先:從起點開始由近及遠進行廣泛搜索,一般使用隊列實現
  • 深度優先:從起點開始沿著一條路徑一直往下,直到不能搜索為止,再折返沿著另一條路徑往下搜索,使用或者遞歸實現

  • 下面將以上圖中的樹來舉例實現搜索,每個節點的數據結構如下

    public static class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;} }

    廣度優先搜索

  • 從根節點開始遍歷,將根節點加入隊列,隊列為[50]
  • 將隊首節點50的所有子節點按照從左到右的順序加入隊列,隊列為[50,3,67]
  • 將節點50移出隊列,隊列為[3,67]
  • 重復步驟2、3直到所有節點遍歷完畢,即可完成廣度優先搜索
  • 遍歷結果:50, 3, 67, 1, 34, 55, 13, 23

    java代碼實現如下

    /*** 廣度優先搜索* @param root* @return*/public int[] bfs(TreeNode root) {if (root == null) {return new int[0];}List<Integer> result = new LinkedList<>();Queue<TreeNode> queue = new LinkedList<>();queue.add(root); /* 將根節點放入隊列 */while (!queue.isEmpty()) {TreeNode node = queue.poll(); /* 取出隊首節點node */result.add(node.val);if (node.left != null) {queue.add(node.left); /* 將node的左節點加入隊列 */}if (node.right != null) {queue.add(node.right); /* 將node的右節點加入隊列 */}}return result.stream().mapToInt(Integer::intValue).toArray();}

    深度優先搜索

    根據節點的遍歷順序,深度優先搜索分為先序遍歷、中序遍歷和后序遍歷。

  • 先序遍歷:先輸出當前節點,再遍歷左節點,最后遍歷右節點。遍歷左、右節點時,依然按照先序遍歷的規則遍歷。
  • 中序遍歷:先遍歷左節點,再輸出當前節點,最后遍歷右節點。遍歷左、右節點時,依然按照中序遍歷的規則遍歷。
  • 后序遍歷:先遍歷左節點,再遍歷右節點,最后輸出當前節點。遍歷左、右節點時,依然按照后續遍歷的規則遍歷。
  • 先序遍歷

    輸出結果:50, 3, 1, 34, 13, 23, 67, 55

    /*** 深度優先搜索-先序遍歷,遞歸實現** @param root* @return*/public int[] dfsPreorder(TreeNode root) {List<Integer> result = new LinkedList<>();dfsPreorder(root, result);return result.stream().mapToInt(Integer::intValue).toArray();}public void dfsPreorder(TreeNode node, List<Integer> result) {if (node == null) {return;}result.add(node.val); // 輸出當前節點dfsPreorder(node.left, result); // 遍歷左節點dfsPreorder(node.right, result); // 遍歷右節點}

    先序遍歷棧實現思路:

  • 先序遍歷順序為:輸出當前節點 → 遍歷左節點 → 遍歷右節點
  • 可以從根節點開始,優先遍歷左子樹,最后再遍歷右子樹,將所有節點按照遍歷順序輸出即可得到先序遍歷結果
  • /*** 深度優先搜索-先序遍歷,棧實現** @param root* @return*/public int[] dfsPreorder(TreeNode root) {List<Integer> result = new LinkedList<>();Stack<TreeNode> stack = new Stack<>();TreeNode node = root;while (node != null || !stack.isEmpty()) {if (node != null) {stack.push(node); result.add(node.val); // 輸出當前節點node = node.left; // 向左遍歷} else {node = stack.pop();node = node.right; // 向右遍歷}}return result.stream().mapToInt(Integer::intValue).toArray();}

    中序遍歷

    輸出結果:1, 3, 13, 23, 34, 50, 55, 67

    /*** 深度優先搜索-中序遍歷,遞歸實現** @param root* @return*/public int[] dfsMidOrder(TreeNode root) {List<Integer> result = new LinkedList<>();dfsMidOrder(root, result);return result.stream().mapToInt(Integer::intValue).toArray();}public void dfsMidOrder(TreeNode node, List<Integer> result) {if (node == null) {return;}dfsMidOrder(node.left, result); // 遍歷左節點result.add(node.val); // 輸出當前節點dfsMidOrder(node.right, result); // 遍歷右節點}

    中序遍歷棧實現思路:

  • 中序遍歷順序為: 遍歷左節點 → 輸出當前節點 → 遍歷右節點
  • 從根節點開始,優先遍歷左子樹,最后再遍歷右子樹,將所有節點按照出棧輸出即可得到先序遍歷結果
  • 注意:中序遍歷要求左節點優先輸出,所以節點入棧時不要輸出,待節點出棧再輸出

    /*** 深度優先搜索-中序遍歷,棧實現** @param root* @return*/public int[] dfsMidOrder(TreeNode root) {List<Integer> result = new LinkedList<>();Stack<TreeNode> stack = new Stack<>();TreeNode node = root;while (node != null || !stack.isEmpty()) {if (node != null) {stack.push(node); // 當前節點入棧node = node.left; // 向左遍歷} else {node = stack.pop(); // 棧頂元素沒有左節點,此時向右遍歷result.add(node.val);node = node.right; // 向右遍歷}}return result.stream().mapToInt(Integer::intValue).toArray();}

    后序遍歷

    輸出結果:1, 23, 13, 34, 3, 55, 67, 50

    /*** 深度優先搜索-后序遍歷,遞歸實現** @param root* @return*/public int[] dfsPostorder(TreeNode root) {List<Integer> result = new LinkedList<>();dfsPostorder(root, result);return result.stream().mapToInt(Integer::intValue).toArray();}public void dfsPostorder(TreeNode node, List<Integer> result) {if (node == null) {return;}dfsPostorder(node.left, result); // 遍歷左節點dfsPostorder(node.right, result); // 遍歷右節點result.add(node.val); // 輸出當前節點}

    后序遍歷棧實現思路:

  • 后序遍歷順序為:遍歷左節點 → 遍歷右節點 → 輸出當前節點
  • 按照棧先進后出的特點,入棧順序應為:當前節點 → 右節點 → 左節點
  • 可以從根節點開始,優先遍歷右子樹,最后再遍歷左子樹,將所有節點按照遍歷順序保存到棧中,最后按順序出棧即可得到后序遍歷結果
  • /*** 深度優先搜索-后續遍歷,棧實現** @param root* @return*/public int[] dfsPostorder(TreeNode root) {List<Integer> result = new LinkedList<>();Stack<TreeNode> stack = new Stack<>();TreeNode node = root;while (node != null || !stack.isEmpty()) {if (node != null) {stack.push(node); // 入棧順序是后序遍歷的倒敘排列result.add(0, node.val); // 將倒敘變為正序node = node.right; // 向右遍歷} else {node = stack.pop().left; // 向左遍歷}}return result.stream().mapToInt(Integer::intValue).toArray();}

    總結

    以上是生活随笔為你收集整理的树-广度优先和深度优先搜索算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。