平衡二叉樹的基本操作

平衡二叉樹定義及操作原理

C++簡單實(shí)現(xiàn)

涉及練習(xí)題目:平衡二叉樹的基本操作

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>


using namespace std;

//二叉樹節(jié)點(diǎn)定義,由于需要算平衡因子故在一般二叉樹的基礎(chǔ)上增加height屬性 
struct node{
    int data, height;
    struct node *lchild;
    struct node *rchild;
};

//獲取某個(gè)節(jié)點(diǎn)的高度片仿,高度從葉子節(jié)點(diǎn)算起砂豌,葉子節(jié)點(diǎn)高度為1 
int getHeight(node *root){
    if(root == NULL)
        return 0;
    return root->height;
}

//更新某個(gè)節(jié)點(diǎn)的高度,取其左右子樹中較大的一個(gè) 
void updateHeight(node *root){
    root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
}
//獲取某個(gè)節(jié)點(diǎn)的平衡因子筐摘,為左子樹高度減去右子樹高度 
int getBaFa(node *root){
    return getHeight(root->lchild) - getHeight(root->rchild);
}
//平衡二叉樹的左旋操作 
void L(node* &root){
    //使用temp首先指向需要左旋的節(jié)點(diǎn)的右子樹 
    node *temp = root->rchild;
    //進(jìn)行左旋操作咖熟,前提保證二叉樹的大小順序不變馍管,即仍是一棵二叉查找樹 
    root->rchild = temp->lchild;
    temp->lchild = root;
    //左旋后更新兩個(gè)變換后的節(jié)點(diǎn)的高度,注意順序首先更新root因?yàn)楝F(xiàn)在root已經(jīng)成為temp的子節(jié)點(diǎn)
    //應(yīng)該從上到下更新 
    updateHeight(root);
    updateHeight(temp);
    //左旋后的根結(jié)點(diǎn)變?yōu)榱藅emp 
    root = temp;
}
//右旋操作罗捎,和左旋操作相同 
void R(node* &root){
    node *temp = root->lchild;
    root->lchild = temp->rchild;
    temp->rchild = root;
    updateHeight(root);
    updateHeight(temp);
    root = temp;
}
//平衡二叉樹的元素插入桨菜,和一般二叉查找樹的不同是需要在插入后判斷是否平衡
//即需要實(shí)時(shí)更新節(jié)點(diǎn)的高度雷激,計(jì)算平衡因子承桥,并進(jìn)行旋轉(zhuǎn)操作 
void insert(node* &root, int x){
    if(root == NULL){
        root = new node;
        root->data = x;
        root->height = 1;
        root->lchild = root->rchild = NULL;
        return ;
    }
    if(x < root->data){
        //插入到左子樹 
        insert(root->lchild, x);
        //更新當(dāng)前節(jié)點(diǎn)的高度 
        updateHeight(root);
        //如果平衡因子變?yōu)?了凶异,表示出現(xiàn)了不平衡現(xiàn)象 
        if(getBaFa(root) == 2){
            //不平衡的現(xiàn)象有兩種剩彬,一種是LL型,一種是LR型母廷,需根據(jù)左孩子的平衡因子判斷 
            //為1時(shí)是LL型氓鄙,直接對前節(jié)點(diǎn)右旋即可
            //為-1時(shí)是LR型抖拦,需要先對左孩子進(jìn)行左旋态罪,再對當(dāng)前節(jié)點(diǎn)進(jìn)行右旋 
            if(getBaFa(root->lchild) == 1)
                R(root);
            else if(getBaFa(root->lchild) == -1){
                L(root->lchild);
                R(root);
            }
        }
        
    }
    else{
        //插入右子樹复颈,相關(guān)的情況和插入左子樹相同君纫,不平衡的情況仍然有兩種
        //一種是RR型蓄髓,一種是Rl型 
        insert(root->rchild, x);
        updateHeight(root);
        if(getBaFa(root) == -2){
            if(getBaFa(root->rchild) == -1)
                L(root);
            else if(getBaFa(root->rchild) == 1){
                R(root->rchild);
                L(root);
            }
        }
    }
}
//平衡二叉樹的查找操作 
int search(node* root, int x){
    //為空則返回陡叠,表示查找完后仍未查找到 
    if(root == NULL)
        return 0;
    //等于查找的數(shù)即返回1表示查找到 
    if(x == root->data)
        return 1;
    //小于時(shí)在左子樹查找 
    else if(x < root->data)
        search(root->lchild, x);
    //大于時(shí)在右子樹查找 
    else
        search(root->rchild, x);
}

int main() {
    int n, k;
    while(scanf("%d%d", &n, &k) != EOF) {
        node *root = NULL;
        int a;
        //輸入n個(gè)數(shù)構(gòu)建平衡二叉樹 
        for(int i = 0; i < n; i++){
            scanf("%d", &a);
            insert(root, a);
        }
        //輸入元素查找 
        for(int i = 0; i < k; i++){
            scanf("%d", &a);
            if(search(root, a))
                printf("1 ");
            else
                printf("0 "); 
        }
        printf("\n");
    }

    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末译红,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拙徽,更是在濱河造成了極大的恐慌膘怕,老刑警劉巖岛心,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讳癌,死亡現(xiàn)場離奇詭異晌坤,居然都是意外死亡骤菠,警方通過查閱死者的電腦和手機(jī)商乎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來专控,“玉大人伦腐,你說我怎么就攤上這事幸冻。” “怎么了庞溜?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長旅掂。 經(jīng)常有香客問我商虐,道長秘车,這世上最難降的妖魔是什么叮趴? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮妻率,結(jié)果婚禮上宫静,老公的妹妹穿的比我還像新娘券时。我一直安慰自己捌袜,他們只是感情好震檩,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布博其。 她就那樣靜靜地躺著慕淡,像睡著了一般峰髓。 火紅的嫁衣襯著肌膚如雪携兵。 梳的紋絲不亂的頭發(fā)上徐紧,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機(jī)與錄音嘲碧,去河邊找鬼愈涩。 笑死钠署,一個(gè)胖子當(dāng)著我的面吹牛谐鼎,可吹牛的內(nèi)容都是我干的狸棍。 我是一名探鬼主播草戈,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼丙猬,長吁一口氣:“原來是場噩夢啊……” “哼茧球!你這毒婦竟也來了抢埋?” 一聲冷哼從身側(cè)響起揪垄,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤饥努,失蹤者是張志新(化名)和其女友劉穎肪凛,沒想到半個(gè)月后伟墙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體戳葵,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伤锚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擅笔。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屯援,靈堂內(nèi)的尸體忽然破棺而出猛们,到底是詐尸還是另有隱情,我是刑警寧澤狞洋,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布弯淘,位于F島的核電站,受9級特大地震影響吉懊,放射性物質(zhì)發(fā)生泄漏假勿。R本人自食惡果不足惜郁惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一虎韵、第九天 我趴在偏房一處隱蔽的房頂上張望测萎。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纲缓。三九已至污筷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背林束。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人性宏。 一個(gè)月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缺脉。 傳聞我的和親對象是個(gè)殘疾皇子礁扮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

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