樹的三種DFS策略(前序、中序、后序)遍歷


之前刷leetcode的時候,知道求排列組合都需要深度優先搜索(DFS), 那么前序、中序、后序遍歷是什么鬼,一直傻傻的分不清楚。直到后來才知道,原來它們只是DFS的三種不同策略。

N = Node(節點)

L = Left(左節點)

R = Right(右節點)

在深度優先搜索的時候,以Node的訪問順序,定義了三種不同的搜索策略:

前序遍歷:結點 —> 左子樹 —> 右子樹

中序遍歷:左子樹—> 結點 —> 右子樹

后序遍歷:左子樹 —> 右子樹 —> 結點

##前序遍歷

前序遍歷

Pre-order: F, B, A, D, C, E, G, I, H.

##中序遍歷 中序遍歷

In-order: A, B, C, D, E, F, G, H, I.

在二叉搜索樹(BST)中,中序遍歷返回遞增的一個序列

##后序遍歷 后序遍歷

Post-order: A, C, E, D, B, H, I, G, F.

##遞歸代碼

遞歸實現比較直觀容易,通常DFS遍歷,都需要傳遞一個參數 or 設置一個全局變量,來保存結果

def pre_order(self, node, results):
    if node is None:
        return
    results.append(node.val)
    self.pre_order(node.left, results)
    self.pre_order(node.right, results)
def in_order(self, node, results):
    if node is None:
        return
    self.in_order(node.left, results)
    results.append(node.val)
    self.in_order(node.right, results)
def post_order(self, node, results):
    if node is None:
        return
    self.post_order(node.left, results)
    self.post_order(node.right, results)
    results.append(node. 大專欄  樹的三種DFS策略(前序、中序、后序)遍歷val)

##非遞歸代碼

深度優先遍歷的非遞歸代碼,一定用到的是stack數據接口

非遞歸實現前序和中序還可以,后續遍歷就非常燒腦了

前序最簡單,相當於for循環所有children,所以一版非遞歸DFS,就用前序就好了。

中序遍歷,由於對於BST有一個遞增的特性,所以還是比較常用的

def preorderTraversal(self, root):
    results = []
    if root is None:
        return results
    stack = [root]
    while(len(stack) > 0):
        node = stack.pop()
        results.append(node.val)
        # right first so left pop fisrt
        if node.right is not None:
            stack.append(node.right)
        if node.left is not None:
            stack.append(node.left)
    return results
def inorderTraversal(self, root):
    results = []
    if root is None:
        return results
    stack = []
    node = root
    while(len(stack) > 0 or node is not None):
        if (node is not None):
            stack.append(node)
            node = node.left
        else:
            node = stack.pop()
            results.append(node.val)
            node = node.right
    return results
def postorderTraversal(self, root):
    results = []
    if root is None:
        return results
    node = root
    stack = []
    lastNodeVisted = None
    while(len(stack) > 0 or node is not None):
        if node is not None:
            stack.append(node)
            node = node.left
        else:
            peek = stack[-1] # last element
            if (peek.right is not None and lastNodeVisted != peek.right):
                node = peek.right
            else:
                results.append(peek.val)
                lastNodeVisted = stack.pop()
    return results

–END–


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM