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


产品介绍
下一篇:没有了