- dfs 包括:
preorder(copy tree), inorder (non-descending order for BST), postorder traversal (delete tree) 的recursive方法还有iterative的方法
http://www.geeksforgeeks.org/618注意比较三种code,pre order 和inorder仅仅是res赋值的位置不一样,postorder
- pre order 不停地遍历左子树,并且每次遍历都给res赋值,都push到stack中。一直到最左的node。然后开始pop到右子树节点,针对此右子树,再找最左node。。。一直到stack和root都为空
- note 这三种遍历方式都是用stack存储scan的路径。先找到最左node,然后backtrace。。。。也为我们提供了找某一点path的方法,stack存储的就是stack.peek的path。
class Solution(object):
def iterative_preorder(self, root, res):
stack = []
while stack or root:
if root:#一直搜left subtree until None.
res.append(root.val)#pre order是在这里加入到res中
stack.append(root)
root = root.left
else:#已经搜到了最left的subtree,这个点得left subtree是None了,所以这里要pop出上一个element,然后求其right subtree
root = stack.pop()
root = root.right
return res
def preorder(self, root, res):
if root:
res.append(root.val)
self.preorder(root.left, res)
self.preorder(root.right, res)
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
#self.preorder(root,res)
self.iterative_preorder(root,res)
return res
- In order
跟pre order类似,也是不停地找最左子树,然后push到stack。只是给res赋值发生在找到最左子树,pop之后。
class Solution(object):
def iterative_inorder(self, root, res):
stack = []
while stack or root:
if root:#一直搜left subtree until None.
stack.append(root)
root = root.left
else:#已经搜到了最left的subtree,这个点得left subtree是None了,所以这里要pop出上一个element,然后求其right subtree
root = stack.pop()
res.append(root.val)#compared with pre order, in order just move the res part here
root = root.right
return res
def inorder(self, root, res):
if root:
self.inorder(root.left, res)
res.append(root.val)
self.inorder(root.right, res)
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
#self.inorder(root, res)
self.iterative_inorder(root,res)
return res
-Post order
解释的很好。stack中先存右子树再存左子树。。。
good explaination http://stackoverflow.com/questions/1294701/post-order-traversal-of-binary-tree-without-recursion
We would push the root node to the stack first. While the stack is not empty, we keep pushing the left child of the node from top of stack. If the left child does not exist, we push its right child. If it’s a leaf node, we process the node and pop it off the stack.
We also use a variable to keep track of a previously-traversed node. The purpose is to determine if the traversal is descending/ascending the tree, and we can also know if it ascend from the left/right.
If we ascend the tree from the left, we wouldn’t want to push its left child again to the stack and should continue ascend down the tree if its right child exists. If we ascend the tree from the right, we should process it and pop it off the stack.
We would process the node and pop it off the stack in these 3 cases:
The node is a leaf node (no children)
We just traverse up the tree from the left and no right child exist.
We just traverse up the tree from the right.
my code:
class Solution(object):
def iterative_postorder(self, root, list):
stack = []
lastVisit = None
while stack or root:
if root:
stack.append(root)
root = root.left
else:
peek = stack[-1]#got the most left subtree node, see wether it has right subtree otherwise go to scan its parent
if peek.right and lastVisit != peek.right:# condition 3
root = peek.right
else:
list.append(peek.val)
lastVisit = stack.pop()
root = None #一直从stack里面拿element,直到这个element有right subtree
def iterative_postorder2(self, root, list):
stack = []
pre = None
if root:
#print root.val
stack.append(root)
while stack:
curr = stack[len(stack) - 1]
c1 = (curr.left == None and curr.right == None) # if current node is leaf node
c2 = (pre == curr.left and curr.right == None) # if current node doesn't have right subtree and last visit node is left subtree
c3 = (pre == curr.right and pre != None)# if last visit is right subtree and right subtree is not None
if c1 or c2 or c3:
list.append(curr.val)
stack.pop()
pre = curr
else:
if curr.right: stack.append(curr.right)
if curr.left: stack.append(curr.left)
return list
def postorder(self, root, res):
if root:
self.postorder(root.left, res)
self.postorder(root.right, res)
res.append(root.val)
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
#self.postorder(root, res)
self.iterative_postorder2(root, res)
return res
这里的dfs其实是travesal版本,用来遍历所有tree node。而dfs可以用来backtracking,在排列组合,搜索解空间问题上常用。
参考排列和组合问题。 以及自己的算法notes中的回溯算法
- bfs的 level order traversal.
- 枚举所有从root到leaf的path
- 给定一个node,找一条从root到它的path
使用post order. return stack
def findPath(self, root, target):
stack = []
lastVisit = None
while stack or root:
if root:
stack.append(root)
root = root.left
else:
peek = stack[-1]
if peek.right and lastVisit != peek.right:
root = peek.right
else:
if peek == target:
return stack
lastVisit = stack.pop()
root = None
return stack
- 常用到stack和queue。
stack可以就用list, stack = [], stack.append()就是push,stack.pop()就是pop