Leetcode94-二叉树中序非递归遍历

说到非递归遍历,很多人可以想到借助栈或者队列,没错,我们层序遍历就是借助队列来实现的。那麽我们今天的中序非递归又是怎末做到的呢?

首先,我们先看看中序遍历的规律,分析思路才能更方便写代码

 

如上图所示的二叉树,我们都知道中序遍历是:左子树----根节点----右子树。遍历结果为:3 2 1 5 4 6

从结果以及中序遍历的特点可以看出,从根节点一直向左下,直到拿到根节点左子树的最左节点(也就是3),然后才打印3、2、1

由此我们便可以联想到栈的特性:先进后出

同时我们把根节点的右子树也看成一颗二叉树,遍历结果是:5 4 6.也是将左子树一次入栈,直到最后一个左子树节点,然后访问栈顶元素并将其出栈,再判断是否有右子树

至此 我们可以总结一下:

1>先找以root为根的左子树最左下的节点,并保存所经路径的所有节点---》保存到栈里。

2>然后遍历栈顶的元素并将栈顶元素出栈-------->先打印栈顶元素并且出栈,然后再判断栈顶的是否有右孩子
 
3>获取栈顶元素(也就是root根节点左下的节点)判断是否有右子树
  • 如果该栈顶元素有右孩子: 将该右孩子当作以刚才遍历左子树的方式继续入栈;
  • 没有右孩子: 直接出栈
方法一:
 

class Solution {
    //找到左子树最左下的节点
    private void leftOrder(TreeNode cur,Stack<TreeNode> stack)
    {
        //有左子树节点
         while(cur!=null)
        {
            //先入栈
            stack.push(cur);
            cur=cur.left;
        }
    }


    public List<Integer> inorderTraversal(TreeNode root)    {
         List<Integer> list=new ArrayList();
        if(root==null)
        {
            return list;
        }
       
        TreeNode cur=root;
        Stack<TreeNode> stack=new Stack<>();
        leftOrder(cur,stack);

       //判断栈顶元素是否有右孩子
       while(!stack.empty())
       {
            if(stack.peek().right!=null)
            {//有右孩子,让其按照寻找最左下节点继续遍历
               list.add(stack.peek().val);
               TreeNode lcur=stack.pop();
               leftOrder(lcur.right,stack);


            }else{//栈顶元素没有右孩子
            //遍历并出栈
                list.add(stack.peek().val);
                stack.pop();
            }       
       }
        return list;
    }
}

 

方法二:
class Solution {
  

    public List<Integer> inorderTraversal(TreeNode root)    {
         List<Integer> list=new ArrayList();
        if(root==null)
        {
            return list;
        }
       //1.先找根节点的最做下的节点,并且将该路径上的所有节点保存到栈里
        TreeNode cur=root;
        Stack<TreeNode> stack=new Stack<>();

        while(!stack.empty() ||cur!=null)
        {
            //有左子树节点
             while(cur!=null)
            {
               //先入栈
              stack.push(cur);
              cur=cur.left;
            }
 //2.得到最左下节点--->栈顶元素
            TreeNode node=stack.peek();
            
  //3.打印栈顶元素,并且判断是否有右子树
            if(stack.peek().right!=null)
            {//有右孩子,让其按照寻找最左下节点继续遍历
               list.add(stack.peek().val);
               cur=stack.pop().right;//栈顶出栈,并将cur置为栈顶的右孩子

            }else{//栈顶元素没有右孩子
            //遍历并出栈
                list.add(stack.peek().val);
                stack.pop();
            }  
        }
        return list;
    }
}

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值