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


产品介绍
下一篇:没有了