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


付款方式