非递归遍历二叉树
前序遍历
思想:一个栈存放节点(初始时存放一个根节点),每次pop出一个节点并记录其值,然后将节点的左右子节点依次入栈(如果存在)
// 前序遍历
func preOrder(root *TreeNode) []int {
var stack []*TreeNode
var ans []int
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
ans = append(ans, node.Val)
if node.Left != nil {
stack = append(stack, node.Left)
}
if node.Right != nil {
stack = append(stack, node.Right)
}
}
return ans
}
后序遍历
思想:和前序一样,只是调换一下左右子节点的入栈顺序,最后再将结果逆序处理即可
// 后序遍历
func postOrder(root *TreeNode) []int {
var stack []*TreeNode
var ans []int
for len(stack) > 0 {
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
ans = append(ans, node.Val)
if node.Right != nil {
stack = append(stack, node.Right)
}
if node.Left != nil {
stack = append(stack, node.Left)
}
}
for i := 0; i < len(ans)/2; i++ {
ans[i], ans[len(ans)-1-i] = ans[len(ans)-1-i], ans[i]
}
return ans
}
中序遍历
思想:一个cur指针指向当前节点,如果cur不为nil就将cur指向的节点入栈,再将cur移到左孩子,当cur为nil时,再从栈顶pop出节点(一定是cur的后继),记录值,并将cur移到右孩子(一定是cur的后继)
// 中序遍历
func midOrder(root *TreeNode) []int {
var stack []*TreeNode
var ans []int
cur := root
for {
if cur != nil {
stack = append(stack, cur)
cur = cur.Left
} else {
if len(stack) == 0 {
break
}
node := stack[len(stack)-1]
stack = stack[:len(stack)-1]
ans = append(ans, node.Val)
cur = node.Right
}
}
return ans
}