刚碰到这个,来做个总结:
二叉树遍历分为:先序遍历—> 根--左--右
中序遍历—> 左--根--右
后序遍历—> 左--右--根
先是
# -*- coding:utf-8 -*-
# class ATree(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# 先序遍历
class Solution(object):
def front_search(self, root):
if not root.val:
return
print(root.val)
self.front_search(root.left)
self.front_search(root.right)
# 中序遍历
class Solution(object):
def mid_search(self, root):
if not root.val:
return
self.mid_search(root.left)
print(root.val)
self.mid_search(root.right)
# 后序遍历
class Solution(object):
def back_search(self, root):
if not root.val:
return
self.back_search(root.left)
self.back_search(root.right)
print(root.val)
我这样展示可以清晰看到三种遍历的差异,仅仅是父节点的存储位置不同,而左右节点顺序是一样的。由此可以写出非递归的算法。
非递归:
# 先续遍历
class Solution(object):
def front_search(self, root):
if not root:
return
res = []
stack = []
while stack or root:
while root:
res.append(root.val)
stack.append(root)
root = root.left
root = stack.pop()
root = root.right
return res
先序遍历思路:从根节点开始遍历左子树,并把节点存入栈stack中,当节点为空,从栈stack退到上一节点去查右节点,不断重复
不好意思,触摸板画的,有点丑,不过基本思路是和上文解释一致。
# 中续遍历
class Solution(object):
def mid_search(self, root):
if not root:
return
res = []
stack = []
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
res.append(root.val)
root = root.right
return res
# 后续遍历
class Solution(object):
def back_search(self, root):
if not root:
return
res = []
stack = []
while stack or root:
while root:
res.append(root.val)
stack.append(root)
root = root.right
root = stack.pop()
root = root.left
return res[::-1]
中序遍历和递归类似,改变父节点顺序就行。但是后序遍历就比较复杂,需要从左孩子先到右孩子,再到父节点,非常复杂。我看到一个很方便的方法:把后序遍历反过来,即先 根--右--左,遍历完整棵树后,在倒序输出,即是后序。根--右--左的遍历就和先序非常像了,把left和right交换就行。
层序遍历 求深度和宽度
class Node(object):
def __init__(self, val):
self.left = None
self.right = None
self.val = val
class Solution:
def calc_binary_tree(self, root: Node)-> (int, int):
layout = [root]
max_width = 0
max_height = 0
while layout:
max_height += 1
max_width = max(max_width, len(layout))
new_layout = []
for node in layout:
if node.left:
new_layout.append(node.left)
if node.right:
new_layout.append(node.right)
layout = new_layout
return max_width, max_height