当前位置:   article > 正文

BST的后续遍历_bst中序遍历的结果

bst中序遍历的结果

真没想到一个非递归中序遍历也能搞死我。我是有多弱啊,更别说后续遍历了。

看看人家的代码,那真是八仙过海,各显神通,弱爆了就是我啊就是我

方法1: 参考http://blog.csdn.net/wzy_1988/article/details/17072953

  1. ArrayList<Integer> s1(TreeNode root){
  2. ArrayList<Integer> list=new ArrayList<Integer>();
  3. Stack<TreeNode> st=new Stack<TreeNode>();
  4. TreeNode pre=null;
  5. while(st.size()>0||root!=null){
  6. if(root!=null){
  7. st.push(root);
  8. root=root.left;
  9. }else{
  10. root=st.pop();
  11. if(root.right==null||root.right==pre){
  12. list.add(root.val);
  13. pre=root;
  14. root=null;
  15. }else{
  16. st.push(root);
  17. root=root.right;
  18. }
  19. }
  20. }
  21. return list;
  22. }

先看一下大神1的方法,和中序前序遍历一样,首先遍历最左子树,这个没问题,一直走while里的if模块。

一直走到左子树没有了,这时候pop一下取出来最后一个点。这时候,

如果是中序遍历就可以直接加上这个点然后走右边了,

如果是先序遍历更简单,在if里就add到list里就行,这里也是直接走右孩子就可以。

 

    但是这是后序遍历,后序遍历里中间节点最后查看,所以这里要判断一下,如果没有右孩子或者右边孩子已经遍历过(pre来存上次遍历的点),那么就可以加入这个点了。也就是两个else中间的代码,注意这里有一句root=null值得分析一下。其实这里还有一个隐式约定:root==null既是循环增加左子树完毕的判定条件,也是后面遍历过程中要求pop新节点的请求条件。

     然后就简单了,如果不能加入这个点,对不起还得把你塞回去,然后下一次遍历root.right就ok。 


如果顺着先序和中序写下来多半想到的是这种方法。


方法2: 参考http://www.cnblogs.com/TenosDoIt/p/3416835.html

  1. ArrayList<Integer> s2(TreeNode root){
  2. ArrayList<Integer> list=new ArrayList<Integer>();
  3. Stack<TreeNode> st=new Stack<TreeNode>();
  4. if(root==null)
  5. return list;
  6. st.push(root);
  7. TreeNode pre=null;
  8. while(st.size()>0){
  9. root=st.peek();
  10. if((root.left==null&&root.right==null)||(pre!=null&&(pre==root.left||pre==root.right))){
  11. list.add(root.val);
  12. pre=root;
  13. st.pop();
  14. }else{
  15. if(root.right!=null)
  16. st.push(root.right);
  17. if(root.left!=null)
  18. st.push(root.left);
  19. }
  20. }
  21. return list;
  22. }

再看看大神2的方法,这两种方法复杂度肯定是完全一致的,但思路却完全不同。

连循环加入左节点的步骤都省下了,真是太猛了。

第一步,root入栈。

第二步,peek一个节点。然后分两种情况判断:

   情况1: 如果是叶节点,或者刚处理了它的左节点或者右节点(注意!这里一定要加上左节点,不然必错,想想为啥?),那么就在list上假如这个结果,pop了这个节点,pre记录下处理了这个节点。

   情况2: 非情况1的情况,即这点或者不是叶节点,且,这个点的左右子节点都没有处理,那么处理这个点。处理方式:st.push(root.right); st.push(root.left);


   咱们走一遍整个逻辑,假设树={1,2,3,4,5,6,7}先走根节点,不是叶节点且子节点都没处理,所以加入3,2。循环走完第一遍,peek=2,假如5,4,循环第二遍走完。

第三遍: peek=4,叶节点,加入4为第一个值,pre=4;

第四遍:peek=5 加入结果 4,5  pre=5

5: peek=2,pre=5,为右孩子,4,5,2

6:peek=3, add 7,6, stack=1,3,7,6 pre=5

peek 6 peek 7 peek 3 peek 1 结束。


怎么看怎么那个pre=root.left判不到对吧,再来个树1,2,3,4,#,#,#, 再走一遍就明白了,走4之后,没有右孩子,所以走2,你没有pre=root.left 不是找死么





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/274892
推荐阅读
相关标签
  

闽ICP备14008679号