C++實(shí)現(xiàn)二叉樹(shù)的創(chuàng)建以及四種遍歷方式(遞歸與非遞歸)

C++實(shí)現(xiàn)二叉樹(shù)的創(chuàng)建以及四種遍歷方式(遞歸與非遞歸)


語(yǔ)言這個(gè)東西不用真的會(huì)忘携狭, 我記得前前后后C++的基本語(yǔ)法我也看了好幾遍了捆昏,一直沒(méi)有動(dòng)手寫(xiě)過(guò)什么東西米诉,所以一遍遍的看肛著,一遍遍的忘... ...

正好最近在看數(shù)據(jù)結(jié)構(gòu)藤肢,想著自己用C++來(lái)實(shí)現(xiàn)一下太闺,一方面是熟悉整個(gè)邏輯過(guò)程,加深對(duì)數(shù)據(jù)結(jié)構(gòu)的理解嘁圈,另一方面省骂,也熟悉一下C++。

下圖是我們要?jiǎng)?chuàng)建的二叉樹(shù)最住,其中的#代表空字符钞澳;

二叉樹(shù)

為了驗(yàn)證我們程序的正確性,現(xiàn)給出此二叉樹(shù)的四種遍歷結(jié)果:

前序遍歷(Preorder traversal): A B C D E F G H I J

中序遍歷(Inorder traversal): C D B F E A I H G J

后序遍歷(Postorder traversal):D C F E B I H J G A

層序遍歷(Levelorder traversal):A B G C E H J D F I

此二叉樹(shù)中温学,共有結(jié)點(diǎn)10個(gè)略贮;深度為4;葉子結(jié)點(diǎn)格式為4,分別為D,F,I,J.

二叉樹(shù)節(jié)點(diǎn)的結(jié)構(gòu)體定義

struct Node {
    char data;
    Node* lchild, * rchild;
    Node() = default;
    explicit Node(char data) : data(data) { lchild = nullptr; rchild = nullptr; }
    Node(char data, Node* left, Node* right) : data(data), lchild(left), rchild(right) {}
};

using BiTree = Node*; //起別名

創(chuàng)建二叉樹(shù)(遞歸逃延,通過(guò)前序遍歷創(chuàng)建)

void create(BiTree& node) {
    char ch;
    cin >> ch;
    if (ch == '#') // '#' => null character
        node = nullptr;
    else {
        node = new Node;
        node->data = ch;
        create(node->lchild); //遞歸
        create(node->rchild);
    }
}

要?jiǎng)?chuàng)建上圖所示的二叉樹(shù)览妖,我們要輸入它的前序遍歷:ABC#D##EF###GHI###J##

前序遍歷、中序遍歷以及后序遍歷(遞歸實(shí)現(xiàn))

// 遞歸:實(shí)現(xiàn)前序遍歷 DLR

void preTraversal(BiTree root) {
    if (root == nullptr) {
        return;
    }
    cout << root->data << " ";
    preTraversal(root->lchild);
    preTraversal(root->rchild);
}

// 遞歸:實(shí)現(xiàn)中序遍歷 LDR

void inTraversal(BiTree root) {
    if (root == nullptr) {
        return;
    }
    inTraversal(root->lchild);
    cout << root->data << " ";
    inTraversal(root->rchild);
}

// 遞歸:實(shí)現(xiàn)后序遍歷 LRD

void postTraversal(BiTree root) {
    if (root == nullptr) {
        return;
    }
    postTraversal(root->lchild);
    postTraversal(root->rchild);
    cout << root->data << " ";
}

層序遍歷

// 層序遍歷

void LevelorderTraversal(BiTree root) {
    if (root == nullptr)
        return;  
    queue<BiTree> que; 
    que.push(root);
    while (!que.empty()) {  
        auto node = que.front();
        que.pop();
        cout << node->data << " ";  ;
        if (node->lchild != nullptr)
            que.push(node->lchild);
        if (node->rchild != nullptr)
            que.push(node->rchild);
    }
}

前序遍歷揽祥、中序遍歷以及后序遍歷(非遞歸實(shí)現(xiàn))

//非遞歸:實(shí)現(xiàn)二叉樹(shù)的中序遍歷

void InOrderTranversal(BiTree root) {
    BiTree cur = root;
    stack<BiTree> cs;
    while (cur || !cs.empty()) {
        if (cur != nullptr) {
            cs.push(cur);
            cur = cur->lchild;
        }
        else {
            cur = cs.top();
            cs.pop();
            cout << cur->data << " ";
            cur = cur->rchild;
        }
    }
}

// 非遞歸:實(shí)現(xiàn)二叉樹(shù)的前序遍歷

void PreOrderTranversal(BiTree root) {
    vector<char> result;
    stack<BiTree> st;
    if (root == nullptr)
        return;
    st.push(root);
    while (!st.empty()) {
        auto node = st.top(); //node類(lèi)型為BiTree,也就是Node*
        st.pop();
        result.push_back(node->data);
        if (node->rchild != nullptr)
            st.push(node->rchild);
        if (node->lchild != nullptr)
            st.push(node->lchild);
    }
    Print(result);
}

// 非遞歸:實(shí)現(xiàn)二叉樹(shù)的后序遍歷

void PostOrderTranversal(BiTree root) {
    vector<char> result;
    stack<BiTree> st;
    if (root == nullptr)
        return;
    st.push(root);
    while (!st.empty()) {
        auto node = st.top();
        st.pop();
        result.push_back(node->data);
        if (node->lchild != nullptr)
            st.push(node->lchild);
        if (node->rchild != nullptr)
            st.push(node->rchild);
    }
    reverse(result.begin(), result.end());
    Print(result);
}

計(jì)算二叉樹(shù)的深度

int getDepth(BiTree root) {
    if (root == nullptr)
        return 0;
    return max(getDepth(root->lchild), getDepth(root->rchild)) + 1;
}

計(jì)算二叉樹(shù)中的結(jié)點(diǎn)個(gè)數(shù)

int getNodeCount(BiTree root) {
    if (root == nullptr) {
        return 0;
    }
    int l = getNodeCount(root->lchild);
    int r = getNodeCount(root->rchild);
    int count = l + r + 1;
    return count;
}

計(jì)算二叉樹(shù)葉子結(jié)點(diǎn)的個(gè)數(shù)

int getLeafNodeCount(BiTree root) {
    if (root == nullptr)
        return 0;
    if (root->lchild == nullptr && root->rchild == nullptr)
        return 1;
    return getLeafNodeCount(root->lchild) + getLeafNodeCount(root->rchild);
}

測(cè)試代碼

/*
 * Software:Visual Studio 2022 Community
 * Created by xiaoxin_zh@foxmail.com
 * Implementing Binary Tree with C++
 */

#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>

using std::cin;
using std::cout;
using std::endl;
using std::stack;
using std::vector;
using std::queue;
using std::max;

int main() {
    BiTree T;
    cout << "Please enter the data of the node, # stands for empty : "; //ABC#D##EF###GHI###J##
    create(T);
    cout << "Created successfully!" << endl;
    cout << "===========Preorder traversal=========== " << endl;
    preTraversal(T);
    cout << endl;
    cout << "===========Inorder traversal=========== " << endl;
    inTraversal(T);
    cout << endl;
    cout << "===========Postorder traversal=========== " << endl;
    postTraversal(T);
    cout << endl;
    cout << "************Preorder traversal************" << endl;
    PreOrderTranversal(T);
    cout << endl;
    cout << "************Inorder traversal************" << endl;
    InOrderTranversal(T);
    cout << endl;
    cout << "************Postorder traversal************" << endl;
    PostOrderTranversal(T);
    cout << endl;
    cout << "************Leverlorder traversal************" << endl;
    LevelorderTraversal(T);
    cout << endl;
    cout << "The number of nodes in the binary tree is " << getNodeCount(T) << "." << endl;
    cout << "The depth of the binary tree is " << getDepth(T) << "." << endl;
    cout << "The number of leaf nodes in the binary tree is " << getLeafNodeCount(T) << "." << endl;
    return 0;
}

執(zhí)行結(jié)果

執(zhí)行結(jié)果

以上代碼均已通過(guò)測(cè)試讽膏,如果有問(wèn)題請(qǐng)大家指出,我及時(shí)修改拄丰,以免造成誤導(dǎo)~

by xiaoxin_zh

2022/5/23

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末府树,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子料按,更是在濱河造成了極大的恐慌奄侠,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件载矿,死亡現(xiàn)場(chǎng)離奇詭異垄潮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)闷盔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)弯洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人逢勾,你說(shuō)我怎么就攤上這事牡整。” “怎么了溺拱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵逃贝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我盟迟,道長(zhǎng)秋泳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任攒菠,我火速辦了婚禮迫皱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辖众。我一直安慰自己卓起,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布凹炸。 她就那樣靜靜地躺著戏阅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啤它。 梳的紋絲不亂的頭發(fā)上奕筐,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天舱痘,我揣著相機(jī)與錄音,去河邊找鬼离赫。 笑死芭逝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的渊胸。 我是一名探鬼主播旬盯,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翎猛!你這毒婦竟也來(lái)了胖翰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤切厘,失蹤者是張志新(化名)和其女友劉穎萨咳,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體迂卢,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡某弦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了而克。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怔毛,死狀恐怖员萍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拣度,我是刑警寧澤碎绎,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站抗果,受9級(jí)特大地震影響筋帖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冤馏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一日麸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逮光,春花似錦代箭、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至杜漠,卻和暖如春极景,著一層夾襖步出監(jiān)牢的瞬間察净,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工盼樟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塞绿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓恤批,卻偏偏與公主長(zhǎng)得像异吻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子喜庞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容