二叉排序树(二叉查找树)及C语言实现

曲目:二叉排序树(二叉查找树)及C语言实现
NJ:
时间:2019/06/08
发行:



后面的学派都是向静态查找表的。,从本条开端,绍介了另第一请教表格。--

静态查找表

在静态请教表格中成功请教管理时,也许搜索成,可以将其用力打;也许搜索化为泡影,执意,表中不注意保留字。,可以将此保留字拔出表中。

静态查找表有多种表现办法,本条绍介了一种用法组织表现静态查找表的成功--二叉排序树(也称为“二叉查找树”)。

是什么二叉排序树?

二叉排序树若非是空

二叉树

,它若非具下面是特点:

  • 二叉排序树中,也许它的根装满有左子树,这么左子树中一切装满的值都不足roo的值;
  • 二叉排序树中,也许其根装满具有右子树,这么,右子树上一切装满的值都是体积的值;
  • 二叉排序树的摆布子树也请求都是二叉排序树;

诸如,

1 执意第一二叉排序树:

图 1 二叉排序树

应用二叉排序树查找保留字

二叉排序树中查找某保留字时,搜索诉讼程序相似地次优二叉树。,在二叉排序树不为空树的让的事情下,率先,将搜索值与树的根装满举行区别。,会有 3 种差别的总算:

  • 也许相当,找到成;
  • 也许区别总算是根装满,则保留字值较大。,这表现保留字能够存躺在其左子树中。;
  • 也许区别总算为根海里的保留字值较小,这表现保留字能够存躺在其右子树中。;

成功效能是:(应用递归式办法)

BiTree SearchBST(BiTree T,KeyType 结症)
    也许递归式诉讼程序 T 为空,找到总算,赢利空值;或许找到成,赢利指导保留字的支持
    if (!T || key==T->data) {
        return T;
    }else 也许(密码)录音)
        他的左孩子的递归式遍历
        return SearchBST(T->lchild, 结症)
    }else{
        递归式遍历其右子级
        return SearchBST(T->rchild, 结症)
    }
}

二叉排序树中拔出保留字

二叉排序树自行是静态查找表的一种表现版式,偶尔在搜索诉讼程序中会拔出或用力打表正中鹄的元素,当鉴于搜索化为泡影而需求拔出录音元素时,该录音元素的拔出场所必然坐落在二叉排序树的叶子及梗和枝海里,而且必然的是增长末尾第一装满wh的左子装满或右子装满。。

诸如,在图 1 的二叉排序树中做查找保留字 1 的管理,找到保留字时 3 当叶装满坐落在,判别表中不注意保留字,此刻的保留字 1 拔出场所是保留字 3 的左孩子。

因而,二叉排序树表现静态查找表做拔出管理,您只需对下面的指定遗传密码做些许更改就可以做到这点。,详细的成功指定遗传密码是:

BOOL SearchBST(BiTree T,KeyType key,BiTree f,BiTree *p){
    //也许 T 支持为空,解说查找化为泡影,令 p 支持指导查找诉讼程序正中鹄的末尾第一叶装满,并赢利未发现的通信
    if (!T){
        *p=f;
        return false;
    }
    也许相当,令 p 支持指导保留字,并赢利找到成通信
    else 也许(密码)==T->录音)
        *p=T;
        return true;
    }
    //也许 key 值比 T 根装满的值很小,查找其左子树;相反地,找到它的适当的子树
    else 也许(密码)录音)
        return SearchBST(T->lchild,key,T,p);
    }else{
        return SearchBST(T->rchild,key,T,p);
    }
}
拔出作用
BOOL InsertBST(BiTree T,ElemType e){
    BiTree p=NULL;
    也许搜索化为泡影,需求成功拔出管理
    if (!SearchBST(T, e,NULL,&p)) {
        设定初值拔出装满
        BiTree s=(BiTree)malloc(sizeof(BiTree));
        s->data=e;
        s->lchild=s->rchild=NULL;
        //也许 p 为空,阐明该二叉排序树为空树,此刻,拔出的装满是整棵树的根装满。
        if (!p) {
            T=s;
        }
        //也许 p 不为 NULL,则 p 指导末尾第一未发现的叶装满,但是经过区别 p 和 e 的值决定 s 究竟是 p 左孩子常右孩子
        else 也许(e)录音)
            p->lchild=s;
        }else{
            p->rchild=s;
        }
        return true;
    }
    //也许找到成,不需求拔出,拔出化为泡影
    return false;
}

经过应用二叉排序树对静态查找表做查找和拔出的管理,同时在中序遍历二叉排序树时,可以获得一切保留字的支配序列。。

诸如,让原二叉排序树为空树,在静态请教表格中 {3,5,7,2,1} 成功查找和拔出管理时,可以体系出第一有钱人表中一切保留字的二叉排序树,使泛滥如图所示。 2 所示:

图 2 二叉排序树拔出诉讼程序

经过不休的查找和拔出管理,终极体系的二叉排序树如图 2(5) 所示。当应用中序遍历算法遍历二叉排序树时,总算序列是:

1 2 3 5 7

,为支配序列。


第一凌乱序列可以经过体系一棵二叉排序树,因而它增加了第一支配的序列。。

二叉排序树中用力打保留字

在搜索诉讼程序中,也许在应用二叉排序树表现的静态查找表中用力打某个录音元素时,您需求同时成用力打装满,更使这棵树为二叉排序树。

让要用力打装满 p,则朝一个方向的二叉排序树来说,需求由于装满 p 在差别的场所成功差别的管理,下面是 3 种能够:

1、海里 p 朝一个方向的叶装满,此刻,您只需求用力打装满。,修正父装满的支持。;
2、海里 p 但是左子树或右子树,此刻,只需求掉换左子树或右子树 p 父装满左子树;
3、海里 p 有左子树和右子树。,处置这种形势有两种办法。:

1)定货单装满 p 树左子树是其父装满左子树;海里 p 右子树是它自己径直前体装满的右子树。,如图 3 所示;

图 3 二叉排序树中用力打海里(1)


2)应用装满 p 径直提倡(或径直按次)掉换装满 p,同时在二叉排序树中对其径直提倡(或径直按次)做用力打管理。如图 4 用径直占卜掉换装满 p:

图 4 二叉排序树中用力打海里(2)

图 4 中,在左图的暗中阶遍历中,总算装满 p 径直前体装满是装满 s,因而径直应用装满。 s 无所作为的生活装满 p,因装满 s 不狂暴的激进分子的孩子。,比照第 2 条支配,将其径直掉换为父装满的右子装满。

详细施行指定遗传密码:(可管理)

#include
#include
#define TRUE 1
#define FALSE 0
#define ElemType int
#define  KeyType int
/* 二叉排序树的装满组织界说 */
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

//二叉排序树查找算法
int SearchBST(BiTree T,KeyType key,BiTree f,BiTree *p){
    //也许 T 支持为空,解说查找化为泡影,令 p 支持指导查找诉讼程序正中鹄的末尾第一叶装满,并赢利未发现的通信
    if (!T){
        *p=f;
        return FALSE;
    }
    也许相当,令 p 支持指导保留字,并赢利找到成通信
    else 也许(密码)==T->录音)
        *p=T;
        return TRUE;
    }
    //也许 key 值比 T 根装满的值很小,查找其左子树;相反地,找到它的适当的子树
    else 也许(密码)录音)
        return SearchBST(T->lchild,key,T,p);
    }else{
        return SearchBST(T->rchild,key,T,p);
    }
}
int InsertBST(BiTree *T,ElemType e){
    BiTree p=NULL;
    也许搜索化为泡影,需求成功拔出管理
    if (!SearchBST((*T), e,NULL,&p)) {
        设定初值拔出装满
        BiTree s=(BiTree)malloc(sizeof(BiTree));
        s->data=e;
        s->lchild=s->rchild=NULL;
        //也许 p 为空,阐明该二叉排序树为空树,此刻,拔出的装满是整棵树的根装满。
        if (!p) {
            *T=s;
        }
        //也许 p 不为 NULL,则 p 指导末尾第一未发现的叶装满,但是经过区别 p 和 e 的值决定 s 究竟是 p 左孩子常右孩子
        else 也许(e) < p->录音)
            p->lchild=s;
        }else{
            p->rchild=s;
        }
        return TRUE;
    }
    //也许找到成,不需求拔出,拔出化为泡影
    return FALSE;
}
//用力打作用
int 用力打(bitree *p)
{
    BiTree q, s;
    //形势 1,海里 p 自行朝一个方向的叶装满,径直用力打那就够了。
    if(!p)->l孥 && !(*p)->rchild){
        *p = NULL;
    }
    else if(!p)->l孥){ 左子树为空,只应用装满 p 右子树的根装满掉换该装满 p 那就够了;
        q = *p;
        *p = (*p)->rchild;
        自在(Q)
    }
    else if(!p)->rchild//右子树为空,只应用装满 p 左子树的根装满掉换该装满 p 那就够了;
        q = *p;
        *p = p)->l孥;//喂批评支持 *p 指导左子树,相反,贮藏在左子树正中鹄的装满地址被分配给供应t p
        自在(Q)
    }
    静止//左、右子树不为空,经过 2 种办法
        q = *p;
        s = p)->l孥;
        //遍历,查找装满 p 径直前体
        while(s->rchild)
        {
            q = s;
            s = s->rchild;
        }
        径直更改装满 p 的值
        P)->录音 = s->data;
        //判别海里 p 左子树 s 有适当的的子树吗?,在两个记录中议论
        if( q != *p ){
            q->rchild = s->lchild;//也许是,用力打径直前体装满时,将前体的左子装满更代替 q 指导装满的子装满
        }else{
            q->lchild = s->lchild;//若非,径直让步左子树。
        }
        收费
    }
    return TRUE;
}
int DeleteBST(BiTree *T, int 结症)
{
    if( !t)//不注意保留字全部含义键的录音元素
        return FALSE;
    }
    else
    {
        if( key == t)->录音 ){
            用力打(T)
            return TRUE;
        }
        else if( key < (*T)->录音)
            应用递归式办法
            return 用力打bst(&(*t)->lchild, 结症)
        }
        else{
            return DeleteBST(&(*T)->rchild, 结症)
        }
    }
}
void 按次(Bitree t)//暗中序列输入
{
    也许(t) == 空)
        return ;
    }
    order(t->lchild);
    printf(%d) ", t->data);
    order(t->rchild);
}
int main()
{
    int i;
    int A〔5〕 = {3,4,2,5,9};
    BiTree T = NULL;
    for( i = 0; i < 5; i++ ){
        InsertBST(&T, a[i]);
    }
    printf("中序遍历二叉排序树:
");
    order(T);
    printf("
");
    printf("用力打3后,中序遍历二叉排序树:
");
    DeleteBST(&T,3);
    order(T);
}

运转总算:

中序遍历二叉排序树:
2 3 4 5 9
用力打3后,中序遍历二叉排序树:
2 4 5 9

总结

应用二叉排序树在查找表中做查找管理的

时期复合物

它与二叉树自行的组织使关心。。哪怕请教表格正中鹄的录音元素使相等,但按次差别,体系出的二叉排序树大不使相等。

诸如:查找表

{45,24,53,12,37,93}

和表

{12,24,37,45,53,93}

各自体系的二叉排序树图下图所示:

图 5 差别建筑的的二叉排序树

应用二叉排序树成功静态查找管理的诉讼程序,确实执意从二叉排序树的根海里到查找元素海里的诉讼程序,故,时期多相与元素得第二名树的吃水使关心。。

为了纠正二叉排序树建筑的时发生如图 5 产生向右转舵所示算法效力的方程式,需求对二叉排序树做“均衡化”处置,把它增加树均衡二叉树

均衡二叉树是成功静态查找表的替代的办法,下一节要点绍介。

点击查看原文:二叉排序树(二叉查找树)及C语言实现


产品介绍