深度優先遍歷DFS
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、對於每個節點來說,先遍歷當前節點,然后把右節點壓棧,再壓左節點(這樣彈棧的時候會先得到左節點遍歷,這是符合深度優先遍歷的要求的)
2、彈棧,拿到棧頂的節點,如果節點不為空,重復步驟1,如果為空,結束遍歷。
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
廣度優先搜索,指的是從圖的一個未遍歷的節點出發,先遍歷這個節點的相鄰節點,再依次遍歷每個相鄰節點的相鄰節點。
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); } } }
