版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dpengwang/article/details/88168641
后续遍历N叉树,也就是先访问子节点再访问父节点。
N叉树的访问没有中序说法,因为没有左右节点的概念,只有父节点和孩子们的访问顺序先后的问题。
方法1 递归
带help函数的递归
class Solution1(object):
def postorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
self.res = []
self.DFS(root)
return self.res
def DFS(self, root):
if root == None:
return
else:
for child in root.children:
self.DFS(child)
self.res.append(root.val)
不带help函数的递归
class Solution1(object):
def postorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
res = []
if root == None:
return res
else:
for child in root.children:
res = res + self.postorder(child)
res += [root.val]
return res
方法2 栈 + 指针
用指针指向上一次访问过的节点,如果上一次访问过的节点是当前节点的最右孩子,即可访问该父节点。这是传统的后续遍历的思想
class Solution2(object):
def postorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
if root == None:
return []
stack = [root]
prev = None
res = []
while(len(stack)):
node = stack[-1]
if node.children == [] or node.children[-1] == prev:
res.append(node.val)
prev = node
stack.pop()
else:
for child in node.children[::-1]:
stack.append(child)
return res
方法3 栈 + dict
用dict保存当前节点已被访问过的孩子节点的index,如果访问完了所有的孩子即可访问该父节点
class Solution3(object):
def postorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
if root == None:
return []
res, stack, pNode, dictionary, prev = [], [], root, {}, None
while(len(stack) or pNode):
if pNode:
# print("a")
stack.append(pNode)
if pNode.children != []:
dictionary[pNode] = 0
pNode = pNode.children[0]
else:
pNode = None
else:
pNode = stack[-1]
if pNode in dictionary and len(pNode.children) > dictionary[pNode]+1:
dictionary[pNode] +=1
pNode = pNode.children[dictionary[pNode]]
else:
res.append(pNode.val)
stack.pop()
pNode = None
return res
小结
对于N叉树的先序后续遍历和二叉树的先序后续遍历有相同也有不同
- 相同的地方比如:先序遍历两种树的入栈方式都是一样的,后续遍历中也都要用一个prev指示上次访问过的节点
- 不同点在于:二叉树的先序访问中可以用栈加指针的形式来完成,在N叉树中就没法做到,因为指针无法指示当前孩子的位置。