C語言——二叉搜索樹

性質(zhì)
設(shè)x為二叉搜索樹上的節(jié)點圈膏,如果y為x的左子樹上的節(jié)點,則有y.key<=x.key鸦采;如果y為x的右子樹上的節(jié)點宾巍,則有y.key>x.key。

二叉搜索樹的節(jié)點刪除
二叉搜索樹的節(jié)點z刪除大致可分為三種情況:
1渔伯、z沒有子節(jié)點顶霞,則簡單刪除z,并修改z父節(jié)點锣吼,用nil代替z稱為父節(jié)點的孩子
2选浑、z有一個孩子節(jié)點c,則用c替代z吐限。
3鲜侥、z有兩個孩子節(jié)點,則需找出z 的后繼節(jié)點诸典。z的后繼節(jié)點必然位于z的右子樹當(dāng)中描函,且為右子樹的最小關(guān)鍵字節(jié)點崎苗。

#include<stdio.h>
#include<stdlib.h>

/******************************************************
 *              二叉搜索樹
 ******************************************************/

/******************************************************
 * data structure and definition
 ******************************************************/

typedef int ElemType;

typedef struct TNode
{
    ElemType key;
    struct TNode *parent;
    struct TNode *left;
    struct TNode *right;
}TNode,*Tree;

typedef enum{
    OK = 0,
    ERROR = -1
}Status;

/******************************************************
 * function     : tree_destroy
 * description  : 銷毀一個以T節(jié)點為根節(jié)點的樹
 * input        : Tree *T
 * output       : Tree *T
 * return value : Status(OK/ERROR)
 * author       : HanyoungXue
 * date         : 2018-04-22
 *******************************************************/

Status tree_destroy(Tree *T){
    if (*T){
        TNode* left = (*T)->left;
        TNode* right = (*T)->right;
        free(*T);
        *T = NULL;
        tree_destroy(&left);
        tree_destroy(&right);
        return OK;
    }
    return ERROR;
}

/******************************************************
 * function     : tree_search
 * description  : 尋找關(guān)鍵字值為key的節(jié)點
 * input        : Tree T,ElemType key
 * output       : N/A
 * return value : TNode* T
 * author       : HanyoungXue
 * date         : 2018-04-22
 ******************************************************/

TNode* tree_search(Tree T,ElemType key){
    if(T==NULL || key==T->key){
        return T; 
    }
    if(key<T->key){
        return tree_search(T->left,key);
    }else{
        return tree_search(T->right,key);
    }
}

/*******************************************************
 * function     : tree_in_order_traverse
 * description  : 中序遍歷輸出以節(jié)點T為根節(jié)點的樹
 * input        : Tree T
 * output       : N/A
 * return value : Status(OK/ERROR)
 * author       : HanyoungXue
 * date         : 2018-04-22
 *******************************************************/
Status tree_in_order_traverse(Tree T){
    if(T!=NULL){
        tree_in_order_traverse(T->left);
        printf("%d\t",T->key );
        tree_in_order_traverse(T->right);
        return OK;
    }
    return ERROR;
}

/************************************************************
 * function     : tree_min
 * description  : 尋找以節(jié)點T為根節(jié)點的二叉樹的最小關(guān)鍵字值的節(jié)點
 * input        : Tree T
 * output       : N/A
 * return value : TNode* T
 * author       : HanyoungXue
 * date         : 2018-04-22
 ************************************************************/


TNode* tree_min(Tree T){

    while(T->left){
        T = T->left;
    }
    return T;
}


/************************************************************
 * function     : tree_max
 * description  : 尋找以節(jié)點T為根節(jié)點的二叉樹的最大關(guān)鍵字值的節(jié)點
 * input        : Tree T
 * output       : N/A
 * return value : TNode* T
 * author       : HanyoungXue
 * date         : 2018-04-22
 ************************************************************/
TNode* tree_max(Tree T){
    while (T->right){
        T = T->right;
    }
    return T;
}

/************************************************************
 * function     : tree_successor
 * description  : 尋找節(jié)點T的后繼節(jié)點
 * input        : TNode* T
 * output       : N/A
 * return value : TNode* y
 * author       : HanyoungXue
 * date         : 2018-04-22
 ************************************************************/
TNode* tree_successor(TNode* T){
    if(T->right){
        return tree_min(T->right);
    }

    TNode* y = T->parent;
    while(y&&y->right == T){
        T = y->right;
        y = T->parent;
    }
    return y;
}

/************************************************************
 * function     : tree_insert
 * description  : 插入關(guān)鍵字為key的節(jié)點
 * input        : Tree *T,ElemType key
 * output       : N/A
 * return value : Status(OK/ERROR)
 * author       : HanyoungXue
 * date         : 2018-04-22
 ************************************************************/
Status tree_insert(Tree *T,ElemType key){
    TNode *z = (TNode *)malloc(sizeof(TNode));
    z->key = key;
    z->left = NULL;
    z->right = NULL;

    TNode *y = NULL;
    TNode *x = *T;

    while(x){
        y = x;
        if(z->key < x->key){
            x = x->left;
        }else{
            x = x->right;
        }
    }

    z->parent = y;

    if(!y){
        *T = z;
    }else if(z->key < y->key){
        y->left = z;
    }else{
        y->right = z;
    }

    return OK;
}

/***********************************************************
 * function     : tree_translate
 * description  : 用一棵子樹替換另一棵子樹
 * input        : Tree *T,TNode *u,TNode *v
 * output       : Tree *T
 * return value : N/A
 * author       : HanyoungXue
 * date         : 2018-04-22
 ***********************************************************/

void tree_translate(Tree *T,TNode *u,TNode *v){
    if(!(u->parent)){
        *T = v;
    }else if(u==u->parent->left){
        u->parent->left = v;
    }else{
        u->parent->right = v;
    }
    if(v){
        v->parent = u->parent;
    }
}

/*********************************************************
 * function     : tree_delete
 * description  : 刪除樹T的某個節(jié)點z
 * input        : Tree *T,TNode *z
 * output       : Tree *T,TNode *z
 * return value : N/A
 * author       : HanyoungXue
 * date         : 2018-04-22
 *********************************************************/

void tree_delete(Tree *T,TNode *z){
    if(!(z->left)){
        tree_translate(T,z,z->right);
    }else if(!(z->right)){
        tree_translate(T,z,z->left);
    }else{
        TNode *y = tree_min(z->right);
        if(y->parent!=z){
            tree_translate(T,y,y->right);
            y->right = z->right;
            y->right->parent = y;
        }
        tree_translate(T,z,y);
        y->left = z->left;
        y->left->parent = y;
        tree_destroy(&z);
    }
}

int main(int argc, char const *argv[])
{
    Tree T;
    int n;
    scanf("%d",&n);

    for (int i = 0; i < n; ++i){
        ElemType key = rand()%100;
        tree_insert(&T,key);
    }

    tree_in_order_traverse(T);
    printf("\n");

    // printf("%d\n", tree_successor(tree_min(T))->key);

    tree_delete(&T,tree_min(T));

    tree_in_order_traverse(T);
    printf("\n");

    tree_delete(&T,tree_search(T,78));

    tree_in_order_traverse(T);
    printf("\n");
    // tree_destroy(&T);

    // tree_in_order_traverse(T);
    return 0;
}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舀寓,隨后出現(xiàn)的幾起案子胆数,更是在濱河造成了極大的恐慌,老刑警劉巖互墓,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件必尼,死亡現(xiàn)場離奇詭異,居然都是意外死亡篡撵,警方通過查閱死者的電腦和手機(jī)判莉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來育谬,“玉大人券盅,你說我怎么就攤上這事√盘矗” “怎么了锰镀?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咖刃。 經(jīng)常有香客問我泳炉,道長,這世上最難降的妖魔是什么嚎杨? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任花鹅,我火速辦了婚禮,結(jié)果婚禮上枫浙,老公的妹妹穿的比我還像新娘翠胰。我一直安慰自己,他們只是感情好自脯,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布之景。 她就那樣靜靜地躺著,像睡著了一般膏潮。 火紅的嫁衣襯著肌膚如雪锻狗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天焕参,我揣著相機(jī)與錄音轻纪,去河邊找鬼。 笑死叠纷,一個胖子當(dāng)著我的面吹牛刻帚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涩嚣,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼崇众,長吁一口氣:“原來是場噩夢啊……” “哼掂僵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顷歌,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤锰蓬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后眯漩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芹扭,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年赦抖,在試婚紗的時候發(fā)現(xiàn)自己被綠了舱卡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡队萤,死狀恐怖灼狰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浮禾,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布份汗,位于F島的核電站盈电,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏杯活。R本人自食惡果不足惜匆帚,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望旁钧。 院中可真熱鬧吸重,春花似錦、人聲如沸歪今。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寄猩。三九已至嫉晶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間田篇,已是汗流浹背替废。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留泊柬,地道東北人椎镣。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像兽赁,于是被迫代替她去往敵國和親状答。 傳聞我的和親對象是個殘疾皇子冷守,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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