leetcode-二叉樹的前序、中序、後序、層序的遞歸和非遞歸實現

1. 二叉樹的遍歷

面試中,尤其是校招面試中(哈哈,社招面試估計是嫌這種題目太簡單,不屑於考察),經常被問到的一個題目就是二叉樹的各種遍歷算法,而我們常見的二叉樹的遍歷方式有前序遍歷、中序遍歷、後序遍歷、層序遍歷,所謂的前序/中序/後序是指遍歷根節點的順序,而層序遍歷則是按照二叉樹的深度方向來遍歷,對應的遍歷節點的順序如下:

  1. 前序遍歷:最先遍歷跟節點。遍歷順序爲 根節點->左子樹->右子樹;
  2. 中序遍歷:中間遍歷根節點。遍歷順序爲 左子樹->根節點->右子樹;
  3. 後序遍歷:最後遍歷根節點。遍歷順序爲 左子樹->右子樹->根節點;
  4. 層序遍歷:從二叉樹的第一層根節點開始遍歷,然後第二層從最左往右遍歷,再是第三層從最左往右遍歷。。。



2. 前序遍歷

題目鏈接:https://leetcode.com/problems/binary-tree-preorder-traversal

2.1. 遞歸實現

下面代碼中的res是全局變量。

def binary_tree_pre_order_traversal(root, res):
    if root:
        res.append(root.val)
        binary_tree_pre_order_traversal1(root.left, res)
        binary_tree_pre_order_traversal1(root.right, res)

2.2. 非遞歸實現

使用棧來保存樹中的節點,我們以列數據結構來實現棧。

def binary_tree_pre_order_traversal(root):
    res = []
    s = []
    if root:
        s.append(root)
    while s:
        root = s.pop()
        res.append(root.val)
        if root.right:
            s.append(root.right)
        if root.left:
            s.append(root.left)

    return res



3. 中序遍歷

題目鏈接:https://leetcode.com/problems/binary-tree-inorder-traversal

3.1. 遞歸實現

下面代碼中的res是全局變量。

def tree_in_order_traversal(root, res):
    if root:
        tree_in_order_traversal1(root.left, res)
        res.append(root.val)
        tree_in_order_traversal1(root.right, res)

3.2. 非遞歸實現

def tree_in_order_traversal(root):
    res = []
    s = []
    while root or s:
        while root:
            s.append(root)
            root = root.left
        root = s.pop()
        res.append(root.val)
        root = root.right
    return res



4. 後序遍歷

4.1. 遞歸實現

下面代碼中的res是全局變量。

def binary_tree_post_order_traversal1(root, res):
    if root:
        binary_tree_post_order_traversal1(root.left, res)
        binary_tree_post_order_traversal1(root.right, res)
        res.append(root.val)

4.2. 非遞歸實現

二叉樹的後續遍歷的非遞歸實現方式之所以難度比前序遍歷、中序遍歷要高(哈哈,不是我說的哈,是leetcode說的,leetcode給後序遍歷的難度tag是hard,而前序遍歷、中序遍歷的難度tag都是medium),是因爲後序遍歷是最後才遍歷根節點,而我們通常的方式是要從上往下遍歷,所以必然會經過根節點,所以必須要保存下來根節點,也必然要先遍歷左節點,所以也要保存下來,因此步驟就會比前序遍歷和中序遍歷更多一些,具體代碼如下:

def binary_tree_post_order_traversal2(root):
    res = []
    s =[]
    while root or s:
        while root:
            s.append(root)
            if root.left:
                root = root.left
            else:
                root = root.right
        root = s.pop()
        res.append(root.val)
        if len(s) > 0 and s[-1].left == root:
            root = s[-1].right
        else:
            root = None
    return res



5. 層序遍歷

題目鏈接:https://leetcode.com/problems/binary-tree-level-order-traversal

def binary_tree_level_order_traversal(root):
    if not root:
        return []
    res = [[root.val]]
    d = deque([root])

    while d:
        tmp_val = []
        for _ in range(0, len(d)):
            tmp_node = d.popleft()
            if tmp_node.left:
                d.append(tmp_node.left)
                tmp_val.append(tmp_node.left.val)
            if tmp_node.right:
                d.append(tmp_node.right)
                tmp_val.append(tmp_node.right.val)
        if tmp_val:
            res.append(tmp_val)

    return res
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章