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


产品介绍
下一篇:没有了