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


以下文章推荐了类似的好听歌曲

联系我们