二叉樹的兩顆子樹有明確的左右之分.
說子樹時必須說明是左子樹/右子樹. 根節點從1開始計數. 高度和深度是從0開始, 層數是從1開始node
2**(i-1)
次方個結點總結點數
最多爲2**(h+1)-1
個結點i/2
i
有左右子節點, 那麼左子樹編號是2*i
, 右節點編號是2*i+1
遍歷即將樹的全部結點訪問一次, 按照節點位置的不一樣分爲前序遍歷, 中序遍歷, 後序遍歷python
# coding:utf-8 """ 二叉樹遍歷 時間複雜度: O(n) """ class BinaryTree(object): def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right def pre(root): """前序遍歷""" if root is None: return print(root.data, end="") pre(root.left) pre(root.right) def mid(root): """中序遍歷""" if root is None: return pre(root.left) print(root.data, end="") pre(root.right) def after(root): """後續遍歷""" if root is None: return pre(root.left) pre(root.right) print(root.data, end="") def level(root): """ 按層級遍歷, 廣度優先遍歷 :param root: :return: """ from collections import deque d = deque([]) d.append(root) while d: node = d.popleft() print(node.data, end="") if node.left: d.append(node.left) if node.right: d.append(node.right) if __name__ == '__main__': root = BinaryTree( 'D', BinaryTree( 'B', BinaryTree('A'), BinaryTree('C') ), BinaryTree( 'E', right=BinaryTree( 'G', BinaryTree('F') ) ) ) pre(root) print("\n") mid(root) print("\n") after(root) print("\n") level(root) """ DBACEGF BACDEGF BACEGFD DBEACGF """
使用隊列數組
# coding:utf-8 from collections import deque class Node(object): def __init__(self, value, left=None, right=None): self.value = value self.left = left self.right = right def width(root): if root is None: return queue = [] d = deque(queue) d.append(root) while d: node = d.popleft() print(node.value), if node.left: d.append(node.left) if node.right: d.append(node.right) if __name__ == '__main__': root = Node('D',Node('B',Node('A'),Node('C')),Node('E',right=Node('G',Node('F')))) width(root) """ D B E A C G F """
使用棧app
# coding:utf-8 """ 深度優先遍歷 """ from collections import deque class Node(object): def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right def depth(root): if root is None: return res = [] d = deque([]) d.append(root) while d: node = d.pop() res.append(node.data) if node.right: d.append(node.right) if node.left: d.append(node.left) return res if __name__ == '__main__': root = Node('D', Node('B', Node('A'), Node('C')), Node('E', right=Node('G', Node('F')))) res = depth(root) assert res == ["D", "B", "A", "C", "E", "G", "F"]
分析: 前序遍歷的第一個值就是根節點, 而後在中序遍歷中找到這個值, 那麼這個值的左邊部分就是當前二叉樹的左子樹部分中序遍歷結果, 這個值的右邊部分就是當前二叉樹的右子樹部分中序遍歷結果. 所以, 經過這個分析, 能夠恢復這顆二叉樹code
#!/usr/bin/env python # coding:utf-8 pre = list('DBACEGF') mid = list('ABCDEFG') after = [] def find_after_tree(pre, mid, after): if len(pre) == 0: return if len(pre) == 1: after.append(pre[0]) return # 根據前序遍歷獲得根節點 root = pre[0] # 在中序遍歷中獲得根節點的位置, 那麼左半部分就是左子樹, 另外是右子樹 n = mid.index(root) find_after_tree(pre[1:n+1], mid[:n], after) find_after_tree(pre[n+1:], mid[n+1:], after) # 最後把根節點添加進去 after.append(root) find_after_tree(pre, mid, after) print after """ ['A', 'C', 'B', 'F', 'G', 'E', 'D'] """
# coding:utf-8 """ 求最大樹深 """ def get_max_depth(root): if root is None: return -1 return max(get_max_depth(root.left), get_max_depth(root.right)) + 1
# coding:utf-8 """ 求兩個樹是否徹底相同 """ def is_same_tree(tree1, tree2): if tree1 is None and tree2 is None: return True elif tree1 and tree2: return tree1.data == tree2.data and is_same_tree(tree1.left, tree2.left) and is_same_tree(tree1.right, tree2.right) else: return False