二叉树
二叉树的前序,中序,后序遍历(递归形式)
二叉树前序遍历 leecode144
# 递归实现,第一次到达目标节点就打印,就叫前序
class Solution(object):
def preorderTraversal(self, root):
if not root:
return root
res = list()
res.append(root.val)
temp = self.preorderTraversal(root.left)
res = res if not temp else res+temp
temp = self.preorderTraversal(root.right)
res = res if not temp else res + temp
return res
非递归版本,其实递归是编译器帮我们实现的栈结构来保存信息,所以我们可以自己实现栈结构来保存我们想保存的信息,在这里其实是保存返回的路径,因为遍历下去如果没有返回的路径就无法做到遍历全部。至于为什么是栈而不是队列,也是显而易见的,队列先进先出,无法做到返回路径。
class Solution(object):
def preorderTraversal(self, root):
if not root:
return root
stack = []
res = []
while root:
res.append(root.val)
if root.right:
stack.append(root.right)
if root.left:
stack.append(root.left)
root = None if not len(stack) else stack.pop()
return res
二叉树中序遍历 leecode 94。非递归最关键的思路是怎么知道第二次到达目标点,这里利用另一个栈来存储,然后弹出对比可知是否第二次到达。
# 非递归
class Solution(object):
def inorderTraversal(self, root):
if not root:
return root
res = []
back_stack = []
stack = []
flag = True
while root:
if stack and stack[-1] == root:
res.append(stack.pop().val)
root = None if not len(back_stack) else back_stack.pop()
continue
else:
stack.append(root)
if root.right:
back_stack.append(root.right)
back_stack.append(root)
if root.left:
back_stack.append(root.left)
root = None if not len(back_stack) else back_stack.pop()
return res
# 递归
class Solution(object):
def inorderTraversal(self, root):
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right) if root else []
但是更加好的做法是单栈实现非递归。解决思路,一直往左走一边压栈,直到碰到空,就从栈中取出节点打印,然后往右走重复上面的流程。这个思路恰恰做到了中序遍历。与前序的只压左右子节点相比,这里先一路压左节点,保证了可以从栈中返回的就是上一个节点,然后通过上一个节点可以到达右节点,解决了回去的问题,而且解决了中序打印的需求。code如下:
class Solution(object):
def inorderTraversal(self, root):
if not root:
return root
res = []
stack = []
while stack or root:
if root: # 节点直接左走到空
stack.append(root)
root = root.left
else: # 返回的上一个节点就可以直接打印
root = stack.pop()
res.append(root.val)
root = root.right
return res
二叉树后序遍历 leecode 145。
# 非递归版本,基本跟中序一样的思路,额外栈记录,把节点入栈的顺序调整
class Solution(object):
def postorderTraversal(self, root):
if not root:
return []
record_stack = []
back_stack = []
res = []
while root:
if record_stack and record_stack[-1] == root:
res.append(record_stack.pop().val)
root = None if not len(back_stack) else back_stack.pop()
continue
record_stack.append(root)
back_stack.append(root)
if root.right:
back_stack.append(root.right)
if root.left:
back_stack.append(root.left)
root = None if not len(back_stack) else back_stack.pop()
return res
# 递归
class Solution(object):
def postorderTraversal(self, root):
if not root:
return []
return self. postorderTraversal(root.left)+self.postorderTraversal(root.right)+[root.val]