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


付款方式
下一篇:没有了