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;
    }
}

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章