91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

中序遍歷的遍歷方式是什么

發布時間:2021-06-18 16:21:34 來源:億速云 閱讀:205 作者:chen 欄目:編程語言

這篇文章主要介紹“中序遍歷的遍歷方式是什么”,在日常操作中,相信很多人在中序遍歷的遍歷方式是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”中序遍歷的遍歷方式是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

中序遍歷的遍歷方法為:對于當前結點,首先遍歷左子樹,然后訪問當前節點,最后遍歷右子樹。中序遍歷是二叉樹遍歷的一種,也叫做中根遍歷、中序周游。

本教程操作環境:windows7系統、C++17版本、Dell G3電腦。

二叉樹是一種重要的數據結構,對二叉樹的遍歷也很重要。這里簡單介紹三種二叉樹中序遍歷的方法。二叉樹的中序遍歷就是首先遍歷左子樹,然后訪問當前節點,最后遍歷右子樹。對于下面的二叉樹,中序遍歷結果如下:

中序遍歷的遍歷方式是什么

結果:[5,10,6,15,2]

直觀來看,二叉樹的中序遍歷就是將節點投影到一條水平的坐標上。如圖:

中序遍歷的遍歷方式是什么

1、遞歸法

這是思路最簡單的方法,容易想到并且容易實現。遞歸的終止條件是當前節點是否為空。首先遞歸調用遍歷左子樹,然后訪問當前節點,最后遞歸調用右子樹。代碼如下:

//recursive
class Solution1 {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ret;
        if(root==NULL)return ret;
        inorderHelper(ret,root);
        return ret;
    }
private:
    void inorderHelper(vector<int>& ret,TreeNode* root)
    {
        if(root==NULL)return;
        inorderHelper(ret,root->left);
        ret.push_back(root->val);
        inorderHelper(ret,root->right);
    }
};

2、迭代法

在迭代方法中,從根節點開始找二叉樹的最左節點,將走過的節點保存在一個棧中,找到最左節點后訪問,對于每個節點來說,它都是以自己為根的子樹的根節點,訪問完之后就可以轉到右兒子上了。代碼如下:

//iterate,using a stack
class Solution2 {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ret;
        if(root==NULL)return ret;
        TreeNode *curr=root;
        stack<TreeNode*> st;
        while(!st.empty()||curr!=NULL)
        {
            while(curr!=NULL)
            {
                st.push(curr);
                curr=curr->left;
            }
            curr=st.top();
            st.pop();
            ret.push_back(curr->val);
            curr=curr->right;
        }
        return ret;
    }
};

這種方法時間復雜度是O(n),空間復雜度也是O(n)。

3、Morris法

這種方法是Morris發明的,看完之后感覺精妙無比。這種方法不使用遞歸,不使用棧,O(1)的空間復雜度完成二叉樹的遍歷。這種方法的基本思路就是將所有右兒子為NULL的節點的右兒子指向后繼節點(對于右兒子不為空的節點,右兒子就是接下來要訪問的節點)。這樣,對于任意一個節點,當訪問完它后,它的右兒子已經指向了下一個該訪問的節點。對于最右節點,不需要進行這樣的操作。注意,這樣的操作是在遍歷的時候完成的,完成訪問節點后會把樹還原。整個循環的判斷條件為當前節點是否為空。例如上面的二叉樹,遍歷過程如下(根據當前節點c的位置):

(1)當前節點為10,因為左兒子非空,不能訪問,找到c的左子樹的最右節點p:

中序遍歷的遍歷方式是什么

結果:[]

(2)找節點c的左子樹的最右節點有兩種終止條件,一種右兒子為空,一種右兒子指向當前節點。下面是右兒子為空的情況,這種情況先要構造,將節點p的右兒子指向后繼節點c,然后c下移:

中序遍歷的遍歷方式是什么

結果:[]

(3)當前節點c的左兒子為空,進行訪問。訪問后將c指向右兒子(即后繼節點):

中序遍歷的遍歷方式是什么

結果:[5]

(4)繼續尋找左子樹的最右節點,這次的終止條件是最右節點為當前節點。這說明當前節點的左子樹遍歷完畢,訪問當前節點后,還原二叉樹,將當前節點指向后繼節點:

中序遍歷的遍歷方式是什么

結果:[5,10]

(5)重復上述過程,直到c指向整棵二叉樹的最右節點:

中序遍歷的遍歷方式是什么

左兒子為空,進行訪問,c轉到右兒子。右兒子為空,不滿足判斷條件,循環結束,遍歷完成。結果如下:

[5,10,6,15,2]

這就是Morris方法,時間復雜度為O(n),空間復雜度是O(1)。代碼如下:

//Morris traversal,without a stack
class Solution3 {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ret;
        if(root==NULL)return ret;
        TreeNode *curr=root;
        TreeNode *pre;
        while(curr)
        {
            if(curr->left==NULL)
            {
                ret.push_back(curr->val);
                curr=curr->right;
            }
            else
            {
                pre=curr->left;
                while(pre->right&&pre->right!=curr)
                    pre=pre->right;
                if(pre->right==NULL)
                {
                    pre->right=curr;
                    curr=curr->left;
                }
                else
                {
                    ret.push_back(curr->val);
                    pre->right=NULL;
                    curr=curr->right;
                }
            }
        }
        return ret;
    }
};

到此,關于“中序遍歷的遍歷方式是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宜宾市| 霍邱县| 巴东县| 保山市| 万全县| 嘉荫县| 时尚| 柯坪县| 大新县| 湘潭市| 措勤县| 镇远县| 山阳县| 荆门市| 葵青区| 平武县| 隆安县| 三亚市| 石门县| 广河县| 乌海市| 诸暨市| 汶上县| 枞阳县| 新密市| 敖汉旗| 阿拉善左旗| 柯坪县| 双流县| 清丰县| 贵南县| 东乡县| 安国市| 成武县| 巨鹿县| 卫辉市| 金沙县| 长丰县| 绿春县| 托克逊县| 金华市|