樹的先序遍歷、中序遍歷、後續遍歷的遞歸與循環詳解

針對二叉樹

滿二叉樹:特點是樹很豐滿,深度爲h且有2^h-1個節點的二叉樹,每個葉子節點的深度都相同

完全二叉樹:如果一個二叉樹除了最右邊位置有葉子節點的缺少,其他很豐滿。

編號:如果父節點爲K,左子爲2K 右子爲2K+1

先序遍歷,中序遍歷,後續遍歷,先中後指的是根節點在遍歷時候的位置。

中序(Inorder)->遞歸

/**
 * 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:
    void inorderHelper(TreeNode* root, vector<int>& res){
        if(root == NULL) return;
        if(root->left){
            inorderHelper(root->left,res);
        }
        res.push_back(root->val); // 代表輸出,即先遍歷根節點
        if(root->right){
            inorderHelper(root->right,res);
        }
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int>res;
        if(root == NULL) return res;
        inorderHelper(root, res);
        return res;


    }
};

中序(Inorder)->->循環
用棧,對左側做壓棧,到最左子節點開始遍歷,然後check最左子節點有沒有右子,如果有繼續壓棧遍歷,如果沒有就開始從棧頂取數據。

/**
 * 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> inorderTraversal(TreeNode* root) {
        vector<int>res;
        if(root == NULL) return res;
        stack<TreeNode*> Sroot;
        TreeNode* temp = root;
        while(Sroot.size() != 0 || temp){
            if(temp){
                Sroot.push(temp);
                temp = temp->left;

            }
            else{
                res.push_back(Sroot.top()->val);
                temp = Sroot.top();
                Sroot.pop();
                temp = temp->right;
            }


        }
        return res;


    }
};

先序->循環
先壓右,後壓左

vector<int> preOrder(TreeNode *root){
    vector<int> res;
    if(root == NULL) return res;
    TreeNode* temp = root;
    stack<TreeNode*> Sroot;
    Sroot.push(temp);

    while(Sroot.size() !=0){
         res.push_back(Sroot.top()->val);
         temp = Sroot.top();
         Sroot.pop();
         if(temp->right) 
            Sroot.push(temp->right);
         if(temp->left)
            Sroot.push(temp->left);



    }
    return res;

後序遍歷,看了leetcode上長姿勢的解法,可能是我太蠢

My Accepted code with explaination. Does anyone have a better idea? pre-order traversal is root-left-right, and post order is left-right-root. modify the code for pre-order to make it root-right-left, and then reverse the output so that we can get left-right-root .

Create an empty stack, Push root node to the stack. Do following while stack is not empty.
2.1. pop an item from the stack and print it.

2.2. push the left child of popped item to stack.

2.3. push the right child of popped item to stack.

reverse the ouput.

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        stack<TreeNode*> nodeStack;
        vector<int> result;
        //base case
        if(root==NULL)
        return result;
        nodeStack.push(root);
    while(!nodeStack.empty())
    {
        TreeNode* node= nodeStack.top();  
        result.push_back(node->val);
        nodeStack.pop();
        if(node->left)
        nodeStack.push(node->left);
        if(node->right)
        nodeStack.push(node->right);
    }
     reverse(result.begin(),result.end());
     return result;

}

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