时间复杂度:O(n)
解题思路
由于递归法非常熟悉,所以只讲迭代法思路。
只要根节点不为空,就将值追加到数组中,并将该根节点入栈,然后令根节点为它的左孩子,重复该步骤。当根节点为空时,就令根节点为栈顶结点的右孩子,开启下一轮遍历过程。
AC代码
迭代法代码和之前做过的中序遍历迭代法实现的代码很相似,下面是中序遍历的题解,可以找到前序遍历与中序遍历迭代法实现的共同之处:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func preorderTraversal(root *TreeNode) []int {
res:=[]int{}
stk:=[]*TreeNode{}
for len(stk)>0||root!=nil{
for root!=nil{
res=append(res,root.Val)
stk=append(stk,root)
root=root.Left
}
root=stk[len(stk)-1].Right
stk=stk[:len(stk)-1]
}
return res
}
感悟
迭代法实现前、中、后序遍历很容易,但是迭代法实现起来就稍稍有些难度了。其实迭代法实现三种遍历和递归法实现一样还是有规律可循的,那就是最外层for循环判断条件为栈非空且根节点非空,外层for循环内部首先就是一个判断条件为根节点非空的for循环,在这个for循环中实现了迭代左子树,跳出该循环就说明根节点为空,那么就令根节点为栈顶结点,根据遍历要求看如何再更新root。