1. 程式人生 > 實用技巧 >Leetcode 94 - 二叉樹的中序遍歷

Leetcode 94 - 二叉樹的中序遍歷

1 題目

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

2 題意

給定一個二叉樹,返回它的中序 遍歷。

示例:

輸入: [1,null,2,3]
   1
    \
     2
    /
   3

輸出: [1,3,2]

進階: 遞迴演算法很簡單,你可以通過迭代演算法完成嗎?

3 思路

author's blog == http://www.cnblogs.com/toulanboy/

3.1 中序遍歷

對於一顆樹,先訪問左子樹,再訪問根節點,最後訪問右子樹

3.2 遞迴解法

直接寫一個函式,負責當前樹的遍歷。空樹就是邊界。

3.3 非遞迴解法

大體思路是使用棧模擬遞迴過程,實現中序遍歷的次序要求。

更具體描述為:

(1)對於一顆樹,依次把右子樹、根、左子樹進棧。這樣出棧時便滿足中序遍歷。

(2)從棧裡面取出頂點,不停進行把右子樹、根、左子樹進棧的過程。

(3)當棧為空,即說明所有節點遍歷完畢。

4 程式碼實現

4.1 遞迴程式碼

//author's blog == http://www.cnblogs.com/toulanboy/
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> ans;
    void inorder(TreeNode* root){
        if(!root)
            return;
        inorder(root->left);//先遍歷左子樹
        ans.push_back(root->val);//再遍歷根節點
        inorder(root->right);//最後遍歷右子樹
    }
    vector<int> inorderTraversal(TreeNode* root) {
        inorder(root);
        return ans;
    }
};

4.2 非遞迴程式碼

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
//author's blog == http://www.cnblogs.com/toulanboy/
class Solution {
public:
    
    vector<int> inorder(TreeNode* root){
        vector<int> ans;
        stack<TreeNode*> order;
        if(root == NULL)
            return ans;

        if(root->right) //先塞右子樹
            order.push(root->right);
        order.push(new TreeNode(root->val));//再塞根
        if(root->left) //最後塞左子樹
            order.push(root->left);

        TreeNode* temp;
        while(!order.empty()){
            temp = order.top();
            order.pop();
            //如果這個點是根或者是葉子,直接輸出
            if(temp->left == NULL && temp->right == NULL){
                ans.push_back(temp->val);
            }
            else{//否則說明這個樹還有子樹,還需要進行左右遍歷
                if(temp->right) //先塞右子樹
                    order.push(temp->right);
                order.push(new TreeNode(temp->val));//再塞根
                if(temp->left) //最後塞左子樹
                    order.push(temp->left);
            }
        }
        return ans;
    }
    vector<int> inorderTraversal(TreeNode* root) {
        return inorder(root);
    }
};