二叉树的遍历——递归非递归实现
Posted sango
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的遍历——递归非递归实现相关的知识,希望对你有一定的参考价值。
一、简介
二叉树的三种遍历方式我相信大家都了然于心,前序遍历、中序遍历、后序遍历。对于这三种遍历的递归实现,我们都不容易忘记。不过,对于非递归实现,我相信会有很多人会跟我一样,背了忘,再背再忘......(很多算法题都是这样,比如各种排序算法的实现)。经过认真观察思考后,发现实现起来是那么的简单,只要记住三者遍历顺序就够了。前序遍历,先访问父节点(中)、然后左子树(左)、最后右子树(右);中序遍历:左、中、右;后序遍历:左、右、中。如果还不明白这三种遍历方式的访问顺序,建议去看看动画的教程。
二、递归实现
递归实现结构很好记,上来写两递归,递归左子树,递归右子树。前序遍历,访问节点(打印节点)在两个递归前面——中、左、右;中序遍历,访问放递归中间——左中右;后序遍历,先两递归,最后才访问——左、中、右。
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 9 def preorder_with_recursion(root): 10 if root is None: 11 return 12 13 print(root.val) 14 preorder_with_recursion(root.left) 15 preorder_with_recursion(root.right) 16 17 18 def inorder_with_recursion( root): 19 if root is None: 20 return 21 22 inorder_with_recursion(root.left) 23 print(root.val) 24 inorder_with_recursion(root.right) 25 26 27 def postorder_with_recursion(self, root): 28 if root is None: 29 return 30 31 postorder_with_recursion(root.left) 32 postorder_with_recursion(root.right) 33 print(root.val) 34
三、非递归实现
非递归不外乎就是我们自己维护一个栈结构,来控制出栈、进栈的时机。对于前序遍历(中、左、右),因为先打印父节点 , 可以理解为访问到就要打印;中序遍历(左、中、右),因为先打印最左子树,因此,我们不断地将左节点压入栈中,直到左子节点为空,出栈打印。后序遍历(左、右、中),访问左子树跟中序遍历的方式相同,唯一区别的是,因为得先打印右子树,因此得把这节点继续存入栈(并处理为已访问),让右子树先进栈出栈,最后才轮到该节点打印。
1 def preorder_with_loop(root): 2 if root is None: 3 return 4 5 stack = [] 6 stack.append(root) 7 while stack: 8 cur = stack.pop() 9 print(cur.val) 10 if cur.right: 11 stack.append(cur.right) 12 if cur.left: 13 stack.append(cur.left) 14 15 16 def inorder_for_loop(root): 17 if root is None: 18 return 19 20 stack = [] 21 cur = root 22 while cur or stack: 23 if cur: 24 stack.append(cur) 25 cur = cur.left 26 else: 27 cur = stack.pop() 28 print(cur.val) 29 cur = cur.right 30 31 32 def postorder_with_loop(root): 33 if root is None: 34 return 35 36 stack = [] 37 cur = root 38 while cur or stack: 39 if cur: 40 stack.append(cur) 41 cur = cur.left 42 else: 43 cur = stack.pop() 44 # 先判断有没有右子树,如果没有直接打印,如果有,继续入栈,等右子树先出栈打印。 45 if cur.right: 46 right = cur.right 47 """ 48 第二次入栈,右子树也随后入栈,因此将右子树设置为None来控制 49 下次出栈时到可以打印,而不是再次访问右子树进入死循环。 50 """ 51 cur.right = None 52 stack.append(cur) 53 cur = right 54 else: 55 print(cur.val) 56 cur = None
以上是关于二叉树的遍历——递归非递归实现的主要内容,如果未能解决你的问题,请参考以下文章