赞
踩
定义:每个 node 的 degree 为 0 或 2,且 degree=0 的 nodes 都在同一层。
depth=k 的树共有
2
k
−
1
2^k-1
2k−1 个 nodes。
定义:
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
前/中/后序遍历,其实指的就是中间节点的遍历顺序(中间节点出现在哪里)。
class TreeNode:
def __init__(self, val, left = None, right = None):
self.val = val
self.left = left
self.right = right
递归的核心:
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
left_lst = self.preorderTraversal(root.left)
right_lst = self.preorderTraversal(root.right)
return [root.val] + left_lst + right_lst
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
left_lst = self.postorderTraversal(root.left)
right_lst = self.postorderTraversal(root.right)
return left_lst + right_lst + [root.val]
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
left_lst = self.inorderTraversal(root.left)
right_lst = self.inorderTraversal(root.right)
return left_lst + [root.val] + right_lst
一般面试中不会要求用迭代的方法实现复杂的题目,主要是考察以非递归的方式实现简单题目的能力。
递归的底层使用栈来实现的,所以迭代的时候其实也是要用栈来实现(相当于手动实现递归)。
但要注意,栈的 LIFO 的特性导致加入元素的顺序应当与最终数组里的结果是相反的。
通过栈的特性,来完成实质上的递归:每当栈的 top element 发生改变的时候,实质是开始了子树的递归。
因为栈的 LIFO,操作时的入栈顺序是中右左。
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
stack = [root]
results = []
while (len(stack) > 0):
curr_node = stack.pop()
results.append(curr_node.val) # middle
if curr_node.right != None: # right
stack.append(curr_node.right)
if curr_node.left != None: # left
stack.append(curr_node.left)
return results
与前序遍历是一样的,只需要进行一些顺序的翻转即可(前序是“中左右”,后序是“左右中”)。
class Solution: def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: if root == None: return [] stack = [root] results = [] while (len(stack) > 0): curr_node = stack.pop() results.append(curr_node.val) if curr_node.left != None: stack.append(curr_node.left) if curr_node.right != None: stack.append(curr_node.right) results.reverse() return results
中序遍历和前后序遍历的代码基础是不同的,没办法像后序一样直接在前序的基础上修改。区别在于,中序遍历的访问节点和处理节点是不同的。
当访问根节点的时候,想要先处理左子树中的元素(而非像之前一样,先处理根节点),所以只有访问到最左边的 leaf 节点时,才能开始处理节点。解决思路是用栈进行其中的记录,而用指针来访问节点,而不像之前一样访问即可以处理。
主要逻辑:
class Solution: def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: if root == None: return [] stack = [] results = [] curr_node = root while (len(stack) > 0 or curr_node != None): if curr_node != None: stack.append(curr_node) curr_node = curr_node.left # left else: curr_node = stack.pop() results.append(curr_node.val) # middle curr_node = curr_node.right # right return results
迭代方法无法像递归一样以统一框架来处理前中后序遍历,最大的原因是中序遍历的处理与访问时分开的(类似于双指针)。
处理方法是将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记(要处理的节点放入栈之后,紧接着放入一个空指针作为标记。
统一的解法采用先全部记录,再进行处理的思路,用栈先收集所有节点,然后在栈中弹出顺序元素。
不过这种统一的迭代方法的理论意义大,实际使用还是正常用迭代和递归即可。
class Solution: def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: if root == None: return [] stack = [root] results = [] while (len(stack) > 0): curr_node = stack.pop() if curr_node != None: if curr_node.right != None: stack.append(curr_node.right) # right if curr_node.left != None: stack.append(curr_node.left) # left stack.append(curr_node) # middle stack.append(None) else: results.append(stack.pop().val) return results
class Solution: def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: if root == None: return [] stack = [root] results = [] while (len(stack) > 0): curr_node = stack.pop() if curr_node != None: stack.append(curr_node) # middle stack.append(None) if curr_node.right != None: stack.append(curr_node.right) # right if curr_node.left != None: stack.append(curr_node.left) # left else: results.append(stack.pop().val) return results
class Solution: def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: if root == None: return [] stack = [root] results = [] while (len(stack) > 0): curr_node = stack.pop() if curr_node != None: if curr_node.right != None: stack.append(curr_node.right) # right stack.append(curr_node) # middle stack.append(None) if curr_node.left != None: stack.append(curr_node.left) # left else: results.append(stack.pop().val) return results
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。