亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實(shí)現(xiàn)二叉樹(shù)非遞歸遍歷算法詳解

 更新時(shí)間:2023年04月23日 09:14:48   作者:命由己造~  
在C++中,二叉樹(shù)非遞歸遍歷是一種常用的算法,可避免遞歸過(guò)程中的系統(tǒng)開(kāi)銷(xiāo)和棧溢出問(wèn)題。非遞歸遍歷算法利用棧數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),可以實(shí)現(xiàn)前序、中序和后序遍歷,是C++程序員必備技能之一

一、二叉樹(shù)的前序遍歷

題目鏈接

我們可以把任何一棵樹(shù)看成左路節(jié)點(diǎn),左路節(jié)點(diǎn)和右子樹(shù)。先訪問(wèn)左路節(jié)點(diǎn),再訪問(wèn)左路節(jié)點(diǎn)的右子樹(shù)。在右子樹(shù)中也重復(fù)這種循環(huán),就是非遞歸遍歷二叉樹(shù)的思想。

解釋?zhuān)?/p>

棧st存放節(jié)點(diǎn),v存放數(shù)值,cur初始化為root。

循環(huán)條件是棧不為空或者cur不為空(訪問(wèn)最后一個(gè)節(jié)點(diǎn)之前棧就已經(jīng)為空了),循環(huán)遍歷左子樹(shù)并且把左子樹(shù)入棧,同時(shí)把值存入v中。然后彈出棧頂元素,并且把棧頂元素的右子樹(shù)賦值給cur,這樣就形成了遍歷。

當(dāng)棧不為空的時(shí)候說(shuō)明還有左路節(jié)點(diǎn)的右子樹(shù)沒(méi)有被訪問(wèn),當(dāng)cur不為空的時(shí)候說(shuō)明還有樹(shù)要被訪問(wèn)。當(dāng)同時(shí)為空的時(shí)候才是訪問(wèn)完成。當(dāng)一個(gè)節(jié)點(diǎn)出棧的時(shí)候說(shuō)明此時(shí)該節(jié)點(diǎn)及該節(jié)點(diǎn)的左子樹(shù)已經(jīng)被訪問(wèn)完成了。

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            while(cur)
            {
                st.push(cur);
                v.push_back(cur->val);
                cur = cur->left;
            }
            TreeNode* node = st.top();
            st.pop();
            cur = node->right;// 轉(zhuǎn)化成子問(wèn)題訪問(wèn)右子樹(shù)
        }
        return v;
    }
};

二、二叉樹(shù)的中序遍歷

題目鏈接

因?yàn)橹行虮闅v的訪問(wèn)順序是左根右,跟前序遍歷不同,所以我們讓左節(jié)點(diǎn)入棧的時(shí)候先不訪問(wèn),出棧(說(shuō)明左子樹(shù)訪問(wèn)完了)時(shí)在訪問(wèn)節(jié)點(diǎn)。

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> v;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while(!st.empty() || cur)
        {
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            TreeNode* node = st.top();
            st.pop();
            v.push_back(node->val);
            cur = node->right;
        }
        return v;
    }
};

三、二叉樹(shù)的后序遍歷

3.1 方法一

首先我們知道后序遍歷就是左右根,而我們可以把訪問(wèn)順序變成根右左,然后再逆置順序。而根右左就跟前序遍歷的方法一樣:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            while(cur)
            {
                st.push(cur);
                v.push_back(cur->val);
                cur = cur->right;
            }
            TreeNode* node = st.top();
            st.pop();
            cur = node->left;
        }
        reverse(v.begin(), v.end());
        return v;
    }
};

3.2 方法二

按照常規(guī)的遍歷方法走左右根,但是這里有一個(gè)問(wèn)題:

當(dāng)訪問(wèn)到根的時(shí)候有兩種情況:

1?? 從左子樹(shù)回來(lái),現(xiàn)在要先訪問(wèn)右子樹(shù)

2?? 從右子樹(shù)回來(lái),左右子樹(shù)已經(jīng)訪問(wèn)完畢,再訪問(wèn)根。

針對(duì)這種情況我們可以在加一個(gè)變量來(lái)確定是第幾次訪問(wèn)根,如果是第一次就訪問(wèn)右子樹(shù),如果是第二次就訪問(wèn)。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<pair<TreeNode*, bool>> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            while(cur)
            {
                st.push(make_pair(cur, false));
                cur = cur->left;
            }
            TreeNode* node = st.top().first;
            if(st.top().second == true)
            {
                st.pop();
                v.push_back(node->val);
            }
            else
            {
                st.top().second = true;
                cur = node->right;
            }
        }
        return v;
    }
};

到此這篇關(guān)于C++實(shí)現(xiàn)二叉樹(shù)非遞歸遍歷算法詳解的文章就介紹到這了,更多相關(guān)C++二叉樹(shù)非遞歸遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)推箱子小游戲源碼

    C++實(shí)現(xiàn)推箱子小游戲源碼

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)推箱子小游戲源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • C++ 實(shí)現(xiàn)多數(shù)的最大公約數(shù)的實(shí)例

    C++ 實(shí)現(xiàn)多數(shù)的最大公約數(shù)的實(shí)例

    這篇文章主要介紹了C++ 實(shí)現(xiàn)多數(shù)的最大公約數(shù)的實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C++輸入輸出注意事項(xiàng)總結(jié)

    C++輸入輸出注意事項(xiàng)總結(jié)

    這篇文章主要介紹了C++輸入輸出注意事項(xiàng)總結(jié),對(duì)C++的輸入輸出各個(gè)注意事項(xiàng)進(jìn)行了很好的總結(jié),需要的朋友可以參考下
    2014-08-08
  • 深入了解C++中基于模板的類(lèi)型擦除

    深入了解C++中基于模板的類(lèi)型擦除

    在C\C++中主要有三種類(lèi)型擦除的方式:基于void*的類(lèi)型擦除、面向?qū)ο蟮念?lèi)型擦除和基于模板的類(lèi)型擦除,本文主要為大家詳細(xì)介紹基于模板的類(lèi)型擦除的相關(guān)知識(shí),需要的可以了解下
    2023-12-12
  • C語(yǔ)言 將字符串逆序輸出的實(shí)例

    C語(yǔ)言 將字符串逆序輸出的實(shí)例

    這篇文章主要介紹了C語(yǔ)言將字符串逆序輸出的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • 深入淺析C/C++?的條件編譯

    深入淺析C/C++?的條件編譯

    條件編譯是指預(yù)處理的時(shí)候根據(jù)條件編譯的指令有條件的選擇源程序中的一部分代碼送給編譯器進(jìn)行編譯,進(jìn)行有選擇性的操作,防止宏替換的內(nèi)容重復(fù)包含,這篇文章主要介紹了C/C++?的條件編譯,需要的朋友可以參考下
    2022-04-04
  • 基于Qt實(shí)現(xiàn)視頻播放器的制作

    基于Qt實(shí)現(xiàn)視頻播放器的制作

    本文主要為大家介紹了如何利用Qt中的qMediaPlayer和qvideowidget實(shí)現(xiàn)視頻文件(avi,mp4….)的播放,并且提供進(jìn)度顯示,還可以通過(guò)拖動(dòng)進(jìn)度條來(lái)變換播放位置,感興趣的可以嘗試一下
    2022-12-12
  • C++ OpenCV實(shí)戰(zhàn)之圖像全景拼接

    C++ OpenCV實(shí)戰(zhàn)之圖像全景拼接

    本文主要介紹了如何使用OpenCV C++ 進(jìn)行圖像全景拼接,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定的幫助,感興趣的可以了解一下
    2022-01-01
  • C++深入講解哈夫曼樹(shù)

    C++深入講解哈夫曼樹(shù)

    給定N個(gè)權(quán)值作為N個(gè)葉子結(jié)點(diǎn),構(gòu)造一棵二叉樹(shù),若該樹(shù)的帶權(quán)路徑長(zhǎng)度達(dá)到最小,稱這樣的二叉樹(shù)為最優(yōu)二叉樹(shù),也稱為哈夫曼樹(shù)(Huffman Tree)。哈夫曼樹(shù)是帶權(quán)路徑長(zhǎng)度最短的樹(shù),權(quán)值較大的結(jié)點(diǎn)離根較近
    2022-05-05
  • 淺談QT打包的兩種方式

    淺談QT打包的兩種方式

    本文主要介紹了淺談QT打包的兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03

最新評(píng)論