二叉树的遍历
线性数组或链表只能单向从头到尾遍历或者反向遍历。所谓二叉树的遍历简单的来说就是访问树中所有的节点各一次,并且在遍历后,将树中的数据转化为线性关系。二叉树可以将每个节点分为左右两个分支
二叉树的特性一律从左向右遍历,那么遍历的方式就分为了三种,分别是
- 中序遍历:左子树->树根->右子树
- 前序遍历:树根->左子树->右子树
- 后序遍历:左子树->右子树->树根
这三种方式的顺序也十分好记,简单来说“从左向右,树根最牛”,意思就是所有遍历的顺序都是从左向右,树根在哪个位置,就属于什么遍历,树根在前面就是前序遍历,树根在中间就属于中序遍历,树根在后面就属于后序遍历
下面分别介绍三种方式遍历的算法实现
-
中序遍历
中序遍历的顺序就是:左子树->树根->右子树
就是从树的左侧逐步向下方移动,直到无法移动,再访问此节点,并向右移动一个节点。如果无法向右移动,就可以返回上层的父节点,然后重复这个步骤
- 遍历左子树
- 遍历树根
- 遍历右子树
这种方式可以采用递归的方法,递归找到最左侧的节点,然后找到右侧,最后找到树根,出口就是节点为空时
""" 中序遍历 """ def inorder(ptr): if ptr != None: inorder(ptr.left) print('[%2d]' % ptr.data,end='') inorder(ptr.right)
-
后序遍历
后序遍历的顺序就是:左子树->右子树->树根
即是先遍历左子树,再遍历右子树,最后遍历根节点,反复重复这个步骤
- 遍历左子树
- 遍历右子树
- 遍历树根
""" 后序遍历 """ def postorder(ptr): if ptr != None: postorder(ptr.left) postorder(ptr.right) print('[%2d]' % ptr.data,end='')
-
前序遍历
前序遍历的顺序就是:树根->左子树->右子树
就是先从根节点遍历,再往左方移动,当无法移动时继续右方移动,接着重复执行此步骤
- 遍历树根
- 遍历左节点
- 遍历右节点
""" 前序遍历 """ def preorder(ptr): if ptr != None: print('[%2d]' % ptr.data,end='') preorder(ptr.left) preorder(ptr.right)
总结一下:
三种遍历方法的算法实现所需要实现的功能类似,只是步骤过程有先后,都是遍历左子树和右子树,不同的地方是看在哪一步之后做出处理
这个递归算法的运行过程细节以中序为例:
""" 中序遍历 """ def inorder(ptr): """ 判断此节点是否为空,不为空进入,如果第一个节点就为空,说明二叉树为空 """ if ptr != None: """ 将下一个左节点调用此函数,为空说明是子树的最左侧,不为空继续将一下个左节点调用,直至找到最左侧 """ inorder(ptr.left) """ 执行了上述代码,找到了最左侧的节点,输出该节点 """ print('[%2d]' % ptr.data,end='') """ 找下一个右节点,注意,执行到这一步,左、中节点已经输出,所以找右节点 """ inorder(ptr.right)
因为二叉树的规则是:左子树 < 根节点 < 右子树
所以使用中序遍历会发现输出的结果已经完成了从小到大的排序
例子:设计程序,中序、后序、前序遍历二叉树
class tree: def __init__(self): self.data = 0 self.left = None self.right = None """ 中序遍历 """ def inorder(ptr): if ptr != None: inorder(ptr.left) print('[%2d]' % ptr.data,end='') inorder(ptr.right) """ 后序遍历 """ def postorder(ptr): if ptr != None: postorder(ptr.left) postorder(ptr.right) print('[%2d]' % ptr.data,end='') """ 前序遍历 """ def preorder(ptr): if ptr != None: print('[%2d]' % ptr.data,end='') preorder(ptr.left) preorder(ptr.right) """ 建立二叉树 """ def create_tree(root,val): newnode = tree() newnode.data = val newnode.left = None newnode.right = None if root == None: root = newnode return root else: current = root while current != None: backup = current if current.data > val: current = current.left else: current = current.right if backup.data > val: backup.left = newnode else: backup.right = newnode return root """ 主程序 """ data = [5,6,24,8,12,3,17,1,9] ptr = None root = None for i in range(9): ptr = create_tree(ptr,data[i]) print("--------------------------") print("中序遍历") inorder(ptr) print('') print('后序遍历') postorder(ptr) print('') print('前序遍历') preorder(ptr)