美文网首页
leetcode:Preorder Traversal(树的先序

leetcode:Preorder Traversal(树的先序

作者: secondtown | 来源:发表于2018-08-24 15:47 被阅读9次

    最终代码请拉到结尾:

    先序遍历:

    若二叉树为空,则不进行任何操作:否则
    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(树的先序

          本文链接:https://www.haomeiwen.com/subject/lptiiftx.html