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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

算法(6)深度优先搜索和广度优先搜索

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

一、深度優先搜索(DFS)

主要思路: 從圖中一個未訪問的頂點 V 開始,沿著一條路一直走到底,然后從這條路盡頭的節點回退到上一個節點,再從另一條路開始走到底,不斷遞歸重復此過程,直到所有的頂點都遍歷完成,它的特點是“不撞南墻不回頭”,先走完一條路,再換一條路繼續走。
例子: 用深度優先搜索遍歷下面的樹

1、我們從根節點1開始遍歷,它相鄰的節點有2,3,4,先遍歷節點2,再遍歷2 的子節點5,然后再遍歷5的子節點9。

2、上圖中一條路已經走到底了,此時就從9回退到上一個節點5,看下節點5是否還有除9以外的節點,沒有繼續回退到2,2 也沒有除5以外的節點,回退到1,1 有除2以外的節點3,所以從節點3開始進行深度優先遍歷,如下:

3、同理從10開始往上回溯到6, 6 沒有除10以外的子節點,再往上回溯,發現3有除6以外的子點7,所以此時會遍歷7。從 7 往上回溯到3,1,發現1還有節點4未遍歷,所以此時沿著4,8進行遍歷,這樣就遍歷完成了。完整的節點的遍歷順序如下:

代碼實現:
(1)遞歸實現
遞歸實現比較簡單,由于是前序遍歷,所以我們依次遍歷當前節點,左節點,右節點即可,對于左右節點來說,依次遍歷它們的左右節點即可,依此不斷遞歸下去,直到葉節點(遞歸終止條件),遞歸的表達性很好,也很容易理解,不過如果層級過深,很容易導致棧溢出。

public class Solution { private static class Node { /** * 節點值 */ public int value; /** * 左節點 */ public Node left; /** * 右節點 */ public Node right; public Node(int value, Node left, Node right) { this.value = value; this.left = left; this.right = right; } } public static void dfs(Node treeNode) { if (treeNode == null) { return; } // 遍歷節點 process(treeNode) // 遍歷左節點 dfs(treeNode.left); // 遍歷右節點 dfs(treeNode.right); } }

(2)非遞歸實現
仔細觀察深度優先遍歷的特點,對二叉樹來說,由于是先序遍歷,所以我們有如下思路:對于每個節點來說,先遍歷當前節點,然后把右節點壓棧,再壓左節點(這樣彈棧的時候會先拿到左節點遍歷,符合深度優先遍歷要求)。彈棧,拿到棧頂的節點,如果節點不為空,重復步驟 1, 如果為空,結束遍歷。
我們以二叉樹為例來看下如何用棧來實現 DFS。使用棧來將要遍歷的節點壓棧,然后出棧后檢查此節點是否還有未遍歷的節點,有的話壓棧,沒有的話不斷回溯(出棧)。

public static void dfsWithStack(Node root) { if (root == null) { return; } Stack<Node> stack = new Stack<>(); // 先把根節點壓棧 stack.push(root); while (!stack.isEmpty()) { Node treeNode = stack.pop(); // 遍歷節點 process(treeNode) // 先壓右節點 if (treeNode.right != null) { stack.push(treeNode.right); } // 再壓左節點 if (treeNode.left != null) { stack.push(treeNode.left); } } }

二、廣度優先搜索(BFS)

廣度優先遍歷,指的是從圖的一個未遍歷的節點出發,先遍歷這個節點的相鄰節點,再依次遍歷每個相鄰節點的相鄰節點。上文所述樹的廣度優先遍歷動圖如下,每個節點的值即為它們的遍歷順序。所以廣度優先遍歷也叫層序遍歷,先遍歷第一層(節點 1),再遍歷第二層(節點 2,3,4),第三層(5,6,7,8),第四層(9,10)。

深度優先遍歷用的是棧,而廣度優先遍歷要用隊列來實現,我們以下圖二叉樹為例來看看如何用隊列來實現廣度優先遍歷。

private static void bfs(Node root) { if (root == null) { return; } Queue<Node> stack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { Node node = stack.poll(); System.out.println("value = " + node.value); Node left = node.left; if (left != null) { stack.add(left); } Node right = node.right; if (right != null) { stack.add(right); } } }

總結

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

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