leetcode:Preorder Traversal(树的先序遍历)

最终代码请拉到结尾:

先序遍历:

若二叉树为空,则不进行任何操作:否则
1、访问根结点。
2、先序方式遍历左子树。
3、先序遍历右子树。

简称:根左右

以下图为例进行先序遍历:

image.png

遍历过程如下:

[A,A left,A right]

-->[A,B,B left, B right,C,C left,C right]

--->[A,B,D,E,C,F,F left,G]

-->[A,B,D,E,C,F,H,G]

理解节点

在对节点TreeNode的抽象中,TreeNode具有三个属性,分别是val、left和right,val表示节点的值,而left和right分别指向左右两个子节点(默认为None)。

image.png

思路

需要一个长度可变的变量来存储结果。这里可以使用列表preorderlist。

从上面的分析,第一步是得到[A,A left,A right]

具体怎么做呢,需要从根节点A出发,然后将preorderList.append(A),然后应该做判断,如果存在左节点,那么就preorderList.append(A.left),如果存在右节点,就preorderList.append(A.right),那么第一步就可以实现[A,A left,A right].

image.png

然后我们怎么进行到下一步,可以令A = A.left或者A = A.right吗?

答案是不行,因为这样我们一步只能完成左边或者右边的添加。而且左右节点可能存在也可能不存在,所以要执行的次数也是不确定的。

解决方法:

额外添加一个数组stack,这个数组存在的作用相当于确定要执行的次数。这么说可能有点悬。还是以上面的数组为例,先让数组stack = []。

先把A添加进stack中。然后再把A从stack中pop出来,这时候只需要pop一个元素(就是A)。再把A添加到preorderList中。然后继续判断node.right和node.left存在与否,如果存在就添加到stack中。

接下来怎么办,继续pop

image.png

也就是说,可以将node = stack.pop()之后的内容变成一个循环。
上面说了左右节点可能存在可能不存在,所以stack.pop()的具体执行次数是不确定,但是反正必须要pop到stack为空。
所以这里可以用while循环。只要stack != [],就继续进行操作。因此上面的代码可以修改成:

image.png

stack的左右问题:

还有一点注意的是,将stack的元素pop出来放到preorderList去的时候,由于最后的结果要求是按照“根左右”的顺序,那么stack中就应该按照“右左”的顺序进行添加,所以先判断node.right,如有右节点先添加右节点。

image.png

你可能感兴趣的:(leetcode:Preorder Traversal(树的先序遍历))