C++學習——二叉樹的操作

前言

二叉樹的原理

代碼實現(xiàn)

/*
二叉樹的學習
參考:https://blog.csdn.net/guokeyan22/article/details/50758922
*/

#include<iostream>
#include<queue>

using namespace std;

/*
二叉樹的結(jié)點
*/

class BinTreeNode
{
private:
    int data;               //數(shù)據(jù)域
    BinTreeNode* left;      //左子樹
    BinTreeNode* right;     //右子樹

public:
    //使用列表初始化結(jié)點
    BinTreeNode(const int& item, BinTreeNode* lPtr = nullptr, BinTreeNode* rPtr = nullptr) :data(item), left(lPtr), right(rPtr) {};
    BinTreeNode() {};
    ~BinTreeNode() {};

public:
    void set_data(int data) {
        this->data = data;
    }

    int get_data() const {
        return this->data;
    }

    void set_left(BinTreeNode* left) {
        this->left = left;
    }

    BinTreeNode* get_left() const {
        return this->left;
    }

    void set_right(BinTreeNode* right) {
        this->right = right;
    }

    BinTreeNode* get_right() {
        return this->right;
    }



private:

};



/*
二叉樹
*/

class  BinTree
{

private:
    BinTreeNode* root;      //根結(jié)點


public:
    BinTree(BinTreeNode* t = nullptr) :root(t) {};
    ~BinTree() { delete root; };

public:
    inline void set_root(BinTreeNode* root) {
        this->root = root;
    }
    
    inline BinTreeNode* get_root() const{
        return this->root;
    }

    //1.創(chuàng)建二叉樹
    BinTreeNode* creat_tree();
    //2.前序遍歷
    void pre_order(BinTreeNode* r)const;
    //3.中序遍歷
    void in_order(BinTreeNode* r)const;
    //4.后序遍歷
    void post_order(BinTreeNode* r)const;
    //5.層序遍歷
    void level_order(BinTreeNode* r)const;
    //6.獲取葉子結(jié)點個數(shù)
    int get_leaf_num(BinTreeNode* r)const;
    //7.獲取二叉樹高度
    int get_tree_height(BinTreeNode* r)const;
    ////8.交換二叉樹的左右子樹/兒子
    //void swap_left_right(BinTreeNode* r);
    ////

};

/*
創(chuàng)建二叉樹
創(chuàng)建一顆二叉樹忱反,可以用前序/中序/后序的方法。 用"#"表示空結(jié)點

@return 二叉樹的根結(jié)點
*/
BinTreeNode * BinTree::creat_tree() {

    char item;
    BinTreeNode* t;
    BinTreeNode* t_r;
    BinTreeNode* t_l;

    cin >> item;

    if (item!='#') {
        BinTreeNode* pTmpNode = new BinTreeNode(item - 48);
        //根結(jié)點
        t = pTmpNode;
        //創(chuàng)建左子樹
        t_l = creat_tree();
        t->set_left(t_l);
        //創(chuàng)建右子樹
        t_r = creat_tree();
        t->set_right(t_r);
        
        return t;
    } else {
        t = nullptr;
        return t;
    }

}

/*
二叉樹的遍歷——前序遍歷
采用遞歸的方式

*/
void BinTree::pre_order(BinTreeNode * r) const {

    if (r!=nullptr) {

        //先遍歷根結(jié)點
        cout << r->get_data() << " ";
        //然后前序遍歷左子樹
        pre_order(r->get_left());
        //最后前序遍歷右子樹
        pre_order(r->get_right());
        
    }
}

/*
二叉樹的遍歷——中序遍歷
采用遞歸的方式
*/
void BinTree::in_order(BinTreeNode * r) const {
    if (r!=nullptr) {
        //先中序遍歷左子樹
        in_order(r->get_left());
        //然后遍歷根結(jié)點
        cout << r->get_data() << " ";
        //最后中序遍歷右子樹
        in_order(r->get_right());
    }
}

/*
二叉樹的遍歷——后序遍歷
*/
void BinTree::post_order(BinTreeNode * r) const {

    if (r!=nullptr) {
        //先后序遍歷左子樹
        post_order(r->get_left());
        //再后續(xù)遍歷優(yōu)子樹
        post_order(r->get_right());
        //最后遍歷根結(jié)點
        cout << r->get_data() << " ";
    }
    

}

/*
二叉樹的遍歷——層序遍歷
二叉樹的層序遍歷類似于廣度優(yōu)先搜索BFS滤愕。 二叉樹的層序遍歷可以使用隊列queue
*/
void BinTree::level_order(BinTreeNode * r) const {

    if (r==nullptr) {
        return;
    }

    queue<BinTreeNode*> q;
    //r進入隊尾(隊列在尾部插入温算,隊頭/首刪除)
    q.push(r);

    while (!q.empty()) {
        //獲取隊首的元素
        BinTreeNode* pTmpNode = q.front();  
        cout << pTmpNode->get_data() << " ";

        //隊頭元素出隊列/刪除
        q.pop();

        if (pTmpNode->get_left()!=nullptr) {
            q.push(pTmpNode->get_left());

        }
        if (pTmpNode->get_right()!=nullptr) {
            q.push(pTmpNode->get_right());
        }
    }

}


/*
獲取二叉樹葉子結(jié)點的個數(shù)
二叉樹葉子結(jié)點個數(shù)=左子樹葉子結(jié)點個數(shù)+右子樹葉子結(jié)點個數(shù)
利用遞歸
@return 葉子結(jié)點個數(shù)
*/
int BinTree::get_leaf_num(BinTreeNode * r) const {
    
    //遞歸終止條件1:該結(jié)點為空
    if (r == nullptr) {
        return 0;
    }

    //遞歸終止條件2:(這是判斷是否為葉子結(jié)點)
    //若該結(jié)點的左子樹,右子樹為空间影,則為葉子結(jié)點
    if (r->get_right()==nullptr&&r->get_left()==nullptr) {
        return 1;
    }

    //遞歸整個書的葉子結(jié)點個數(shù)=左子樹葉子結(jié)點個數(shù)+右子樹葉子結(jié)點個數(shù)
    return get_leaf_num(r->get_left()) + get_leaf_num(r->get_right());

}


/*
計算二叉樹的高度
二叉樹的高度 = max(左子樹高度注竿,右子樹高度)+1
*/
int BinTree::get_tree_height(BinTreeNode * r) const {
    //空結(jié)點
    if (r==nullptr) {
        return 0;
    }

    //葉子結(jié)點
    if (r->get_left()==nullptr&&r->get_right()==nullptr) {
        return 1;
    }

    int l_height = get_tree_height(r->get_left());
    int r_height = get_tree_height(r->get_right());

    return l_height >= r_height ? l_height + 1 : r_height + 1;
}



int main() {

    //實例化一個二叉樹
    BinTree tree;
    //-------------------創(chuàng)建二叉樹---------------------------
    cout << "創(chuàng)建一顆二叉樹,請輸入二叉樹的前序序列,'#'代表空結(jié)點" << endl;
    tree.set_root(tree.creat_tree());
    cout << endl;

    //-------------------前序遍歷二叉樹-----------------------
    cout << "前序遍歷二叉樹的結(jié)果:";
    tree.pre_order(tree.get_root());
    cout << endl;

    //--------------------中序遍歷二叉樹----------------------
    cout << "中序列遍歷二叉樹的結(jié)果:";
    tree.in_order(tree.get_root());
    cout << endl;

    //--------------------后序列遍歷二叉樹--------------------
    cout << "后序遍歷二叉樹的結(jié)果:";
    tree.post_order(tree.get_root());
    cout << endl;

    //--------------------層序遍歷----------------------------
    cout << "層序遍歷二叉樹的結(jié)果:";
    tree.level_order(tree.get_root());
    cout << endl;

    //--------------------計算二叉樹葉子結(jié)點的個數(shù)------------
    cout << "二叉樹葉子結(jié)點的個數(shù):";
    cout << tree.get_leaf_num(tree.get_root());
    cout << endl;

    //--------------------計算二叉樹的高度--------------------
    cout << "二叉樹的高度:";
    cout << tree.get_tree_height(tree.get_root());
    cout << endl;


    system("pause");

}

  • 運行結(jié)果


    image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巩割,一起剝皮案震驚了整個濱河市裙顽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宣谈,老刑警劉巖愈犹,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異闻丑,居然都是意外死亡漩怎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門嗦嗡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勋锤,“玉大人,你說我怎么就攤上這事酸钦」值茫” “怎么了咱枉?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵卑硫,是天一觀的道長。 經(jīng)常有香客問我蚕断,道長欢伏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任亿乳,我火速辦了婚禮硝拧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘葛假。我一直安慰自己障陶,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布聊训。 她就那樣靜靜地躺著抱究,像睡著了一般。 火紅的嫁衣襯著肌膚如雪带斑。 梳的紋絲不亂的頭發(fā)上鼓寺,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音勋磕,去河邊找鬼妈候。 笑死,一個胖子當著我的面吹牛挂滓,可吹牛的內(nèi)容都是我干的苦银。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼墓毒!你這毒婦竟也來了吓揪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤所计,失蹤者是張志新(化名)和其女友劉穎柠辞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體主胧,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡叭首,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了踪栋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焙格。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夷都,靈堂內(nèi)的尸體忽然破棺而出眷唉,到底是詐尸還是另有隱情,我是刑警寧澤囤官,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布冬阳,位于F島的核電站,受9級特大地震影響党饮,放射性物質(zhì)發(fā)生泄漏肝陪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一刑顺、第九天 我趴在偏房一處隱蔽的房頂上張望氯窍。 院中可真熱鬧,春花似錦蹲堂、人聲如沸狼讨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽政供。三九已至,卻和暖如春能犯,著一層夾襖步出監(jiān)牢的瞬間鲫骗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工踩晶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留执泰,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓渡蜻,卻偏偏與公主長得像术吝,于是被迫代替她去往敵國和親计济。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,509評論 25 707
  • “你別排苍,別……”陳溫揚起眉頭沦寂,從樓梯上立了起來,跑到了電梯門口淘衙,“別走传藏,我現(xiàn)在下來找你!” “一分鐘彤守,計時開始毯侦,一...
    李方知閱讀 200評論 0 1
  • 常有朋友諮詢筝蚕,應不應該買小產(chǎn)權(quán)房卦碾?總結(jié)起來,他們想買小產(chǎn)權(quán)房的原因起宽,大概可歸納為三點:1洲胖、沒有購房資格;2燎含、小產(chǎn)權(quán)...
    李霖律師閱讀 207評論 0 0