欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通俗易懂講解C語言與Java中二叉樹的三種非遞歸遍歷方式

 更新時(shí)間:2021年09月15日 16:01:25   作者:飛人01_01  
二叉樹是一種非常重要的數(shù)據(jù)結(jié)構(gòu),很多的數(shù)據(jù)結(jié)構(gòu)都是基于二叉樹的基礎(chǔ)演變過來的。二叉樹的前,中,后3種遍歷方式,因?yàn)闃涞亩x本身就是遞歸定義的,所以采用遞歸的方法來實(shí)現(xiàn)是很簡單的

詳解二叉樹的三種非遞歸遍歷方式(附C、java源碼)

前言

二叉樹的遞歸遍歷方式很簡單,三種遞歸遍歷方式的區(qū)別,只是printf放的位置不一樣而已,這里就不多講了。把前序遍歷代碼貼在這里:

//結(jié)點(diǎn)
struct Node
{
	int val;
	struct Node* left, * right;
};

//前序遍歷
void pre(Node* root) 
{
    if (root == null)
        return;
    printf("%d ",root->val);
    pre(root->left);
    pre(root->right);
}

前序、中序和后序這三種非遞歸的遍歷方式,中序是最為簡單的,其次是前序,再者就是后序,只是個(gè)人感覺??赡苊總€(gè)人感覺都不一樣吧。

一、非遞歸中序遍歷

中序遍歷順序: 左子樹->頭結(jié)點(diǎn)->右子樹。

如圖—出自于《大話數(shù)據(jù)結(jié)構(gòu)》

所以我們首先需要考慮的是將左手邊(左子樹)的結(jié)點(diǎn)壓入棧,當(dāng)?shù)竭_(dá)底部時(shí)(NULL),我們就輸出此時(shí)棧頂?shù)脑亍?/p>

然后轉(zhuǎn)而去添加當(dāng)前結(jié)點(diǎn)的右手邊(右子樹)的結(jié)點(diǎn)到棧里。

#define MAXSIZE 20  //整棵樹最大的結(jié)點(diǎn)數(shù),用于開辟數(shù)組當(dāng)棧使用
typedef struct Node Node;
void in(Node* root)
{
    Node* stack[MAXSIZE] = { 0 };
    int size = 0; //用于指向arr數(shù)組,也是用于表示這個(gè)數(shù)組還有幾個(gè)元素
    while (size != 0 || root != NULL)
    {
        if (root != NULL)
        {
            stack[size++] = root;
            root = root->left;  //繼續(xù)往左子樹走
        }
        else
        {
            //此時(shí)root為NULL,說明來到了左子樹的最底部,此時(shí)輸出棧頂元素,root往右子樹走即可
            printf("%c ", stack[--size]->val);
            root = stack[size]->right;
        }
    }
}

二、非遞歸前序遍歷

前序遍歷順序: 頭結(jié)點(diǎn)->左子樹-> 右子樹

我記得我在B站學(xué)算法的時(shí)候,聽左程云老師所說,一些的遞歸行為,都可以自己用棧來實(shí)現(xiàn)。

確實(shí),三種非遞歸的遍歷方式實(shí)則也是需要自己實(shí)現(xiàn)棧的功能。接下來的前序遍歷方式,要用到寬度優(yōu)先遍歷的思想,如圖:

圖片出自《大話數(shù)據(jù)結(jié)構(gòu)》

先加入第一層的全部數(shù)據(jù),然后在棧中使用第一層數(shù)據(jù)的同時(shí),判斷加入第二層的全部數(shù)據(jù),第三層的也是一樣…

#define MAXSIZE 20  //整棵樹最大的結(jié)點(diǎn)數(shù),用于開辟數(shù)組當(dāng)棧使用
typedef struct Node Node;
void pre(Node* root)
{
    if (root == NULL)
        return;

    Node* stack[MAXSIZE] = { 0 }; //模擬棧
    int size = 0; //代表此時(shí)棧有多少元素
    arr[size++] = root;
    while (size != 0)
    {
        Node* node = stack[--size];
        printf("%c ", node->val);
        //先壓入右孩子,再壓入左孩子。這樣在彈出的時(shí)候才是  先彈出左孩子 然后才是右孩子
        //頭   左   右
        if (node->right != NULL)
            stack[size++] = node->right;
        if (node->left != NULL)
            stack[size++] = node->left;
    }
}

三、非遞歸后序遍歷

在講解了非遞歸的前序遍歷,其實(shí)我們在前序遍歷的基礎(chǔ)之上改一下就能完成后序遍歷。我們在將前序遍歷時(shí),在while循環(huán)里,加入左右孩子結(jié)點(diǎn)時(shí),先加入棧的是右孩子,然后才是左孩子,只有這樣,我們彈出來的順序才是先左后右。

現(xiàn)在我們只需要改一下加入左右孩子的順序時(shí),我們先壓入棧是左孩子,然后再壓入右孩子。 這樣彈出來就是先右再左的順序。那此時(shí)再加上頭結(jié)點(diǎn),那就是 頭結(jié)點(diǎn)->右孩子->左孩子 。 此時(shí)我們從后面往前面讀,就是 左孩子 -> 右孩子 ->頭結(jié)點(diǎn)。這樣就變成了后序遍歷了。。。

圖片出自《大話數(shù)據(jù)結(jié)構(gòu)》

#define MAXSIZE 20  //整棵樹最大的結(jié)點(diǎn)數(shù),用于開辟數(shù)組當(dāng)棧使用
typedef struct Node Node;
void postorder(Node* root)
{
    if (root == NULL)
        return;

    Node* stack1[MAXSIZE] = { 0 }; //主要棧
    Node* stack2[MAXSIZE] = { 0 };  //輔助棧
    int size1 = 0; //主要棧:代表數(shù)組的元素個(gè)數(shù)
    int size2 = 0; //輔助棧: 代表數(shù)組的元素個(gè)數(shù)
    stack1[size1++] = root;
    while (size1 != 0)
    {
        Node* node = stack1[--size1];
        stack2[size2++] = node; //暫時(shí)存入輔助棧

        //先壓入左孩子,再壓入右孩子
        if (node->left != NULL)
            stack1[size1++] = node->left;
        if (node->right != NULL)
            stack1[size1++] = node->right;
    }

    //倒著輸出輔助棧的數(shù)據(jù)即可
    while (size2-- != 0)
        printf("%c ", stack2[size2]->val);
}

非遞歸與遞歸方式的遍歷,有些相似之處,總結(jié)兩種不同的方法,就能更深刻的理解這些方法。最后,C/C++的同學(xué),記得回收malloc開辟的空間哦?。?!

C語言源碼

java語言源碼

下期見啦!??!

到此這篇關(guān)于通俗易懂講解C語言中二叉樹的三種非遞歸遍歷方式的文章就介紹到這了,更多相關(guān)C 二叉樹非遞歸遍歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中4種管理數(shù)據(jù)內(nèi)存的方式總結(jié)

    C++中4種管理數(shù)據(jù)內(nèi)存的方式總結(jié)

    根據(jù)用于分配內(nèi)存的方法,C++中有3中管理數(shù)據(jù)內(nèi)存的方式:自動(dòng)存儲、靜態(tài)存儲和動(dòng)態(tài)存儲。在存在時(shí)間的長短方面,以這三種方式分配的數(shù)據(jù)對象各不相同。下面簡要介紹這三種類型
    2022-09-09
  • 詳解如何使用C++寫一個(gè)線程安全的單例模式

    詳解如何使用C++寫一個(gè)線程安全的單例模式

    這篇文章主要為大家詳細(xì)介紹了如何使用C++寫一個(gè)線程安全的單例模式,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2022-10-10
  • C語言之單向鏈表詳解及實(shí)例代碼

    C語言之單向鏈表詳解及實(shí)例代碼

    這篇文章主要介紹了C語言之單向鏈表的相關(guān)資料,及實(shí)例代碼,幫助大家學(xué)習(xí)參考,,需要的朋友可以參考下
    2016-09-09
  • 在C++中反射調(diào)用.NET的方法(一)

    在C++中反射調(diào)用.NET的方法(一)

    為什么要在C++中調(diào)用.NET呢?接下來通過本文給大家介紹在C++中反射調(diào)用.NET的方法(一),需要的朋友參考下吧
    2017-02-02
  • C++回調(diào)函數(shù)的理解和使用教程

    C++回調(diào)函數(shù)的理解和使用教程

    這篇文章主要給大家介紹了關(guān)于C++回調(diào)函數(shù)的理解和使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解單鏈表

    C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解單鏈表

    這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之單鏈表,鏈表是由一個(gè)個(gè)結(jié)點(diǎn)鏈結(jié)成的。結(jié)點(diǎn)包括數(shù)據(jù)域和指針域兩部分,數(shù)據(jù)域用來存儲數(shù)據(jù)元素的信息,指針域用來存儲下一個(gè)結(jié)點(diǎn)的地址,更詳細(xì)內(nèi)容請需要的小伙伴參考下面文章內(nèi)容
    2022-03-03
  • C++/Qt遍歷多維數(shù)組的3種方式示例

    C++/Qt遍歷多維數(shù)組的3種方式示例

    一維數(shù)組對于存儲和處理一組數(shù)據(jù)很有用,但有時(shí)候,有必要使用多維數(shù)組,下面這篇文章主要給大家介紹了關(guān)于C++/Qt遍歷多維數(shù)組的3種方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 基于c++中的默認(rèn)拷貝函數(shù)的使用詳解

    基于c++中的默認(rèn)拷貝函數(shù)的使用詳解

    本篇文章對c++中默認(rèn)拷貝函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • C++中Qt的安裝與配置步驟詳解

    C++中Qt的安裝與配置步驟詳解

    Qt是一種C++編程框架,用于構(gòu)建圖形用戶界面(GUI)應(yīng)用程序和嵌入式系統(tǒng),無論是初學(xué)者還是經(jīng)驗(yàn)豐富的開發(fā)者,Qt都為構(gòu)建高質(zhì)量、可維護(hù)的應(yīng)用程序提供了豐富的工具和支持,本文主要給大家介紹了C++中Qt的安裝與配置步驟,需要的朋友可以參考下
    2023-12-12
  • C++常用的11種設(shè)計(jì)模式解釋及示例代碼詳解

    C++常用的11種設(shè)計(jì)模式解釋及示例代碼詳解

    c++常用的設(shè)計(jì)模式包括單例模式、工廠模式、抽象工廠模式、適配器模式、裝飾者模式、代理模式、外觀模式、橋接模式、組合模式、享元模式、觀察者模式和命令模式等,這篇文章主要介紹了C++常用的11種設(shè)計(jì)模式解釋及示例,需要的朋友可以參考下
    2023-02-02

最新評論