基础知识
满二叉树
只有度为2或者0的节点,并且所有度为0的节点都在一层
完全二叉树
除了最低层,每一层都填满了,并且最底层也是从左到右填的
二叉搜索树
左节点永远小于父节点,父节点永远小于右节点
平衡二叉树
左右高度相差不超过1
144. 二叉树的前序遍历
题目描述: 144. 二叉树的前序遍历.
解法
递归
class Solution(object):
def preorderTraversal(self, root):
if not root:
return []
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return [root.val] + left + right
迭代
class Solution(object):
def preorderTraversal(self, root):
if not root:
return []
res = []
st = [root]
while st:
node = st.pop()
res.append(node.val)
if node.right:
st.append(node.right)
if node.left:
st.append(node.left)
return res
迭代的主要思路也比较简单,就是我每次只出一个栈(因此root要先放进去),然后再考虑被拿出来的这个有没有左右节点,然后把右节点先放进去(因为顺序是中、左、右,那么放到栈里的顺序就应该是先右后左)
统一的迭代
class Solution(object):
def preorderTraversal(self, root):
res = []
st = []
if root:
st.append(root)
while st:
node = st.pop()
if node:
if node.right:
st.append(node.right)
if node.left:
st.append(node.left)
st.append(node)
st.append(None)
else:
node = st.pop()
res.append(node.val)
return res
统一的迭代的想法就是,将遍历的过程和处理的过程分开来,先遍历,然后父节点之后紧跟一个none来表示这个是父节点,每一个子节点都会变为父节点,所以就算某个节点是某个节点的左节点或者右节点,他最后都会成为一个父节点,这样在遍历他的时候就要先存储再操作
145. 二叉树的后序遍历
题目描述: 145. 二叉树的后序遍历.
解法
递归
class Solution(object):
def postorderTraversal(self, root):
if not root:
return []
left = self.postorderTraversal(root.left)
right = self.postorderTraversal(root.right)
return left + right + [root.val]
迭代
class Solution(object):
def postorderTraversal(self, root):
if not root:
return []
res = []
st=[root]
while st:
node = st.pop()
res.append(node.val)
if node.left:
st.append(node.left)
if node.right:
st.append(node.right)
return res[::-1]
前序遍历中的顺序是:父、左、右,而后序遍历的顺序是:左、右、父,我们可以将前序遍历的内容中,左右反过来,然后再把结果翻转过来,就是后序遍历
统一迭代
class Solution(object):
def postorderTraversal(self, root):
res = []
st = []
if root:
st.append(root)
while st:
node = st.pop()
if node:
st.append(node)
st.append(None)
if node.right:
st.append(node.right)
if node.left:
st.append(node.left)
else:
node = st.pop()
res.append(node.val)
return res
94. 二叉树的中序遍历
题目描述: 94. 二叉树的中序遍历.
解法
递归
class Solution(object):
def inorderTraversal(self, root):
if not root:
return []
left = self.inorderTraversal(root.left)
right = self.inorderTraversal(root.right)
return left + [root.val] + right
迭代
class Solution(object):
def inorderTraversal(self, root):
res = []
cur = root
st = []
while cur or st:
if cur:
st.append(cur)
cur = cur.left
else:
cur = st.pop()
res.append(cur.val)
cur = cur.right
return res
在前序遍历中,由于父节点是先被处理到的,也会被先遍历到,所以整个流程比较简单,但是在中序遍历中,父节点会先被“遍历”到,但是处理则需要先处理左节点,所谓的处理就是获得数值或者是各种操作之类的。所以大致的流程就是,遍历根节点的左节点,并且把每个父节点都加入到栈中,直到遍历到空的位置,这时就可以从栈取出节点进行处理,然后处理这个节点的右节点,当指针指向的节点为空的时候,从栈中取出的节点一定是上一个处理的节点的父节点。
统一的迭代
class Solution(object):
def inorderTraversal(self, root):
res = []
st = []
if root:
st.append(root)
while st:
node = st.pop()
if node:
if node.right:
st.append(node.right)
st.append(node)
st.append(None)
if node.left:
st.append(node.left)
else:
node = st.pop()
res.append(node.val)
return res