二叉树的前中后序遍历全世界

Posted 荻确如此

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的前中后序遍历全世界相关的知识,希望对你有一定的参考价值。



二叉树是数据结构中非常重要的问题,面试大概率考察,这次来实现一下二叉树的前中后序遍历。


如何将所有节点都遍历打印出来呢?经典的方法有三种,前序遍历、中序遍历和后序遍历,其中的前中后,表示的是节点与它的左右子树节点遍历打印的先后顺序。


总的来说,前序遍历就是根,左,右;中序遍历是左,根,右;后序遍历是左,右,根。

实际上,二叉树的前中后序遍历就是一个递归的过程。比如前序遍历,就是先打印根节点,然后再递归地打印左子树,最后递归地打印右子树。


递归的关键,就是能不能写出递归公式:

前序遍历的递推公式:preOrder(r) = print r->preOrder(r->left)->preOrder(r->right)
中序遍历的递推公式:inOrder(r) = inOrder(r->left)->print r->inOrder(r->right)
后序遍历的递推公式:postOrder(r) = postOrder(r->left)->postOrder(r->right)->print r

有了递归公式就好写了:

前序:

def preorderTraversal(self, root):    if root is None:     return     res = []    res.append(root.val)    if root.left:        res.append(self.preorderTraversal(root.left))    if root.right:        res.append(self.preorderTraversal(root.right))    return res

中序:

 def inorderTraversal(self, root): res = [] if not root: return res if root.left:           res.append(self.inorderTraversal(root.left)) res.append(root.val) if root.right:          res.append(self.inorderTraversal(root.right)) return res

后序:

 def postorderTraversal(self, root): res = [] if not root: return res if root.left:           res.append(self.inorderTraversal(root.left)) if root.right: res.append(self.inorderTraversal(root.right))      res.append(root.val) return res

但是,but,however,面试官是绝对不会轻易让你用递归过关的。于是乎就有了新的解法,我们用stack栈去实现各种顺序。


前序如下:

def preorderTraversal(self, root): if root is None: return  res = []    stack = [root]    while stack:        node = stack.pop()        res.append(node.val)        if node.right:            stack.append(node.right)        if node.left:            stack.append(node.left)    return res

先把root给弹出来,把右子树节点死命压进去,然后左子树节点弹出来,最后右子树弹出来,就完成了根左右的顺序。


同理中序:

def inorderTraversal(self, root): if root is None: return  res = []    stack = []    node = root    while node or len(stack) > 0 :  if node:             stack.append(node)             node = node.left         else:             node = stack.pop()             res.append(node.val)             node = node.right     return res

我们先一股脑把左边的一条线全部push到底,也就是走到最左边,然后node最后为None了就开始pop刚刚的stack了,然后因为pop出来的每一个node都是自己这颗树的root,所以看看有没有右孩子,没有那肯定就是要继续pop(),有的话就应该右孩子是下一个要被访问的节点。


最后来看看右序遍历:

def postorderTraversal(self, root): if root is None: return  res = []    stack = [root]    while stack :        node = stack.pop()        res.append(node.val)        if node.left:            stack.append(node.left)        if node.right:            stack.append(node.right)    return res[::-1]

其实思路就一句话,后序遍历是左右中,因为我们第一个放进去的肯定是中(即root),所以我们逆向思维考虑一下,我们按照中右左的顺序放进去,然后返回res[::-1]就行了


这个真的很容易考到哇。。。


禅定时刻

打算一天写一篇了,过过手,也过过脑。。。

zengdiqing


以上是关于二叉树的前中后序遍历全世界的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的前中后序递归和非递归遍历操作代码

二叉树的前中后序遍历

必须掌握,二叉树的前中后序遍历(迭代+递归)详细代码与思路

二叉树的前中后序遍历(非递归实现)

二叉树的前中后序遍历

非递归实现二叉树的前中后序遍历