python数据结构之二叉树的遍历实例
遍历方案
从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
1).访问结点本身(N)
2).遍历该结点的左子树(L)
3).遍历该结点的右子树(R)
有次序:
NLR、LNR、LRN
遍历的命名
根据访问结点操作发生位置命名:
NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。
LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。
LRN:后序遍历(PostorderTraversal) ——访问结点的操作发生在遍历其左右子树之后。
注:由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtlee)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。
遍历算法
1).先序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
a.访问根结点
b.遍历左子树
c.遍历右子树
2).中序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
a.遍历左子树
b.访问根结点
c.遍历右子树
3).后序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
a.遍历左子树
b.遍历右子树
c.访问根结点
一、二叉树的递归遍历:
# -*- coding: utf - 8 - *- class TreeNode(object): def __init__(self, left=0, right=0, data=0): self.left = left self.right = right self.data = data class BTree(object): def __init__(self, root=0): self.root = root def is_empty(self): if self.root is 0: return True else: return False def preorder(self, treenode): '前序(pre-order,NLR)遍历' if treenode is 0: return print(treenode.data) self.preorder(treenode.left) self.preorder(treenode.right) def inorder(self, treenode): '中序(in-order,LNR' if treenode is 0: return self.inorder(treenode.left) print(treenode.data) self.inorder(treenode.right) def postorder(self, treenode): '后序(post-order,LRN)遍历' if treenode is 0: return self.postorder(treenode.left) self.postorder(treenode.right) print(treenode.data) node1 = TreeNode(data=1) node2 = TreeNode(node1, 0, 2) node3 = TreeNode(data=3) node4 = TreeNode(data=4) node5 = TreeNode(node3, node4, 5) node6 = TreeNode(node2, node5, 6) node7 = TreeNode(node6, 0, 7) node8 = TreeNode(data=8) root = TreeNode(node7, node8, 'root') bt = BTree(root) print(u''' #生成的二叉树 # ------------------------ # root # 7 8 # 6 # 2 5 # 1 3 4 # # ------------------------- ''') print('前序(pre-order,NLR)遍历 :\n') bt.preorder(bt.root) print('中序(in-order,LNR) 遍历 :\n') bt.inorder(bt.root) print('后序(post-order,LRN)遍历 :\n') bt.postorder(bt.root)
输出:
#生成的二叉树 # ------------------------ # root # 7 8 # 6 # 2 5 # 1 3 4 # # ------------------------- 前序(pre-order,NLR)遍历 : root 7 6 2 1 5 3 4 8 中序(in-order,LNR) 遍历 : 1 2 6 3 5 4 7 root 8 后序(post-order,LRN)遍历 : 1 2 3 4 5 6 7 8 root
二、.二叉树的非递归遍历
下面就用非递归的方式实现一遍。主要用到了 stack 和 queue维护一些数据节点:
# -*- coding: utf - 8 - *- class TreeNode(object): def __init__(self, left=0, right=0, data=0): self.left = left self.right = right self.data = data class BTree(object): def __init__(self, root=0): self.root = root def is_empty(self): if self.root is 0: return True else: return False def preorder(self, treenode): '前序(pre-order,NLR)遍历' stack = [] while treenode or stack: if treenode is not 0: print(treenode.data) stack.append(treenode) treenode = treenode.left else: treenode = stack.pop() treenode = treenode.right def inorder(self, treenode): '中序(in-order,LNR) 遍历' stack = [] while treenode or stack: if treenode: stack.append(treenode) treenode = treenode.left else: treenode = stack.pop() print(treenode.data) treenode = treenode.right # def postorder(self, treenode): # stack = [] # pre = 0 # while treenode or stack: # if treenode: # stack.append(treenode) # treenode = treenode.left # elif stack[-1].right != pre: # treenode = stack[-1].right # pre = 0 # else: # pre = stack.pop() # print pre.data def postorder(self, treenode): '后序(post-order,LRN)遍历' stack = [] queue = [] queue.append(treenode) while queue: treenode = queue.pop() if treenode.left: queue.append(treenode.left) if treenode.right: queue.append(treenode.right) stack.append(treenode) while stack: print(stack.pop().data) def levelorder(self, treenode): from collections import deque if not treenode: return q = deque([treenode]) while q: treenode = q.popleft() print(treenode.data) if treenode.left: q.append(treenode.left) if treenode.right: q.append(treenode.right) node1 = TreeNode(data=1) node2 = TreeNode(node1, 0, 2) node3 = TreeNode(data=3) node4 = TreeNode(data=4) node5 = TreeNode(node3, node4, 5) node6 = TreeNode(node2, node5, 6) node7 = TreeNode(node6, 0, 7) node8 = TreeNode(data=8) root = TreeNode(node7, node8, 'root') bt = BTree(root) print(u''' #生成的二叉树 # ------------------------ # root # 7 8 # 6 # 2 5 # 1 3 4 # # ------------------------- ''') print('前序(pre-order,NLR)遍历 :\n') bt.preorder(bt.root) print('中序(in-order,LNR) 遍历 :\n') bt.inorder(bt.root) print('后序(post-order,LRN)遍历 :\n') bt.postorder(bt.root) print('层序(level-order,LRN)遍历 :\n') bt.levelorder(bt.root)
输出:
#生成的二叉树 # ------------------------ # root # 7 8 # 6 # 2 5 # 1 3 4 # # ------------------------- 前序(pre-order,NLR)遍历 : root 7 6 2 1 5 3 4 8 中序(in-order,LNR) 遍历 : 1 2 6 3 5 4 7 root 8 后序(post-order,LRN)遍历 : 1 2 3 4 5 6 7 8 root 层序(level-order,LRN)遍历 : root 7 8 6 2 5 1 3 4