二叉树的两颗子树有明确的左右之分.
说子树时必须说明是左子树/右子树. 根节点从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