二叉排序树(二叉查找树)及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语言实现


加入我们