再看后序遍历。由于后序遍历的顺序是左右中,我们把它反过来,则遍历顺序变成中左右,是不是跟前序遍历只有左右结点的差异了呢?然而左右的差异仅仅就是.left和.right的差异,在代码上只有机械的差别。
我们来看代码:
class Solution: def preorderTraversal(self, root): ## 前序遍历 stack = [] sol = [] curr = root while stack or curr: if curr: sol.append(curr.val) stack.append(curr.right) curr = curr.left else: curr = stack.pop() return sol def postorderTraversal(self, root): ## 后序遍历 stack = [] sol = [] curr = root while stack or curr: if curr: sol.append(curr.val) stack.append(curr.left) curr = curr.right else: curr = stack.pop() return sol[::-1]代码的主体部分基本就是.right和.left交换了顺序,且后序遍历在最后输出的时候进行了反向(因为要从中右左变为左右中)
三、层序遍历层序遍历也可以叫做宽度优先遍历:先访问树的第一层结点,再访问树的第二层结点...然后一直访问到最下面一层结点。在同一层结点中,以从左到右的顺序依次访问。
3.1 递归实现递归函数需要有一个参数level,该参数表示当前结点的层数。遍历的结果返回到一个二维列表sol=[[]]中,sol中的每一个子列表保存了对应index层的从左到右的所有结点value值。
class Solution: def levelOrder(self, root): """ :type root: TreeNode :rtype: List[List[int]] """ def helper(node, level): if not node: return else: sol[level-1].append(node.val) if len(sol) == level: # 遍历到新层时,只有最左边的结点使得等式成立 sol.append([]) helper(node.left, level+1) helper(node.right, level+1) sol = [[]] helper(root, 1) return sol[:-1]PS:
Q:如果仍然按层遍历,但是每层从右往左遍历怎么办呢?
A:将上面的代码left和right互换即可
Q:如果仍然按层遍历,但是我要第一层从左往右,第二层从右往左,第三从左往右...这种zigzag遍历方式如何实现?
A:将sol[level-1].append(node.val)进行一个层数奇偶的判断,一个用append(),一个用insert(0,)
if level%2==1: sol[level-1].append(node.val) else: sol[level-1].insert(0, node.val) 3.2 循环实现这里的循环实现不能用栈了,得用队列queue。因为每一层都需要从左往右打印,而每打印一个结点都会在队列中依次添加其左右两个子结点,每一层的顺序都是一样的,故必须采用先进先出的数据结构。
以下代码的打印结果为一个一维列表,没有采用二维列表的形式。
class Solution: def levelOrder(self, root): if not root: return [] sol = [] curr = root queue = [curr] while queue: curr = queue.pop(0) sol.append(curr.val) if curr.left: queue.append(curr.left) if curr.right: queue.append(curr.right) return sol其实,如果需要打印成zigzag形式(相邻层打印顺序相反),则可以采用栈stack数据结构,正好符合先进后出的形式。不过在代码上还要进行其他改动。