从0开始学习数据结构-树与二叉树-二叉排序树③

311 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

二叉排序树的查找

从二叉排序树的定义与构造方法不难看到,将一个数据元素序列构造为一棵二叉排序树以后,要在树中查找序列中某个数据元素存在与否的效率,比直接在序列中采用顺序比较的效率要高得多。其查找过程是:若二叉排序树为空,则查找失败,结束查找,返回信息NULL;否则,将要查找的值与二叉排序树根结点的值进行比较,若相等,则查找成功,结束查找,返回被查到结点的地址,若不等,则根据要查找的值与根结点值的大小关系决定是到根结点的左子树还是右子树中继续查找(查找过程同上),直到查找成功或者查找失败为止。

查找过程是一个递归过程。

1:查找算法

下面给出的非递归算法中,设二叉排序树采用二叉链表存储结构,根结点存储地址为T;item表示要查找的数据元素;p为活动指针。当查找成功时,算法返回数据域值与item相匹配的结点的地址p,否则,返回一个信息NULL,以示查找失败。

//查找算法
BTREE SREACHBST1(BTREE T , datatype item){
    BTREE p =T;
    while (p != NULL){
        if(p->data == item)
            return p;
        if( item <  p->data )
            p=p->lchild;
        else
            p=p->rchild;
    }
    return NULL; // 查找失败,返回空
}

递归算法:

BTREE SREACHBST2(BTREE T, datatype item) {
    if (T == NULL)
        return NULL;
    if (T->data == item)
        return T;
    if (item < T->data)
        return SREACHBST2(T->lchild, item);
    else
        return SREACHBST2(T->rchild, item);
}

2:查找长度

同一个数据元素集合,若对应的数据元素序列不同,得到的二叉排序树自然不同;换一句话说,采用“逐点插人方法”建立二叉排序树时,若从序列中取得数据元素的次序不同,得到的二叉排序树一定不同。也就是说,具有n个结点的二叉排序树不是唯一的。因而,在不同的二叉排序树中进行查找的平均查找长度与二叉排序树的形态有关。为便于分析,先定义一些术语。

平均查找长度(Average Search Length,ASL)确定一个元素在树中位置所需要进行的比较次数的期望值。

二叉树的内路径长度(Internal Path Length,IPL)从二叉树根结点到某结点所经过的分支数目定义为该结点的路径长度。二叉树中所有结点的路径长度之和定义为该二叉树的内路径长度。

二叉树的外路径长度( External Path L.ength,EPL)为了分析查找失败时的查找长度﹐在二叉树中出现空子树时,增加新的空叶结点来代表这些空子树,从而得到一棵扩充后的二叉树。为了与扩充前的二叉树相区别,这些新增添的空的叶结点用小方块代表,称之为外部结点,树中原有的结点称为内部结点。其外路径长度是二叉树中所有外部结点的路径长度之和

根据二叉树的性质,扩充后的二叉树中若具有n个内部结点,则必然有n+1个外部结点(为什么?)。用归纳法不难证明EPL=IPL+2n。

现在分析二叉排序树的查找长度。在n个结点的二叉排序树中,若对每个数据的查找概率相等,则对每个结点查找成功所需的比较次数就是该结点所在的层次数,即等于该结点的路径长度加1。查找成功的平均查找长度为ASL=(IPL+n)/ n

对于不成功的查找,比较次数等于表示该数据元素所在范围的外部结点的路径长度。因此,查找失败时的平均查找长度为 :ASL=EPL/n=(IPL+2n)/(n+1)

考虑到在二叉排序树中查找成功与不成功的全部可能性,设对扩充后的二叉树的每个结点(包括内部结点和外部结点)进行查找的概率相等,则平均查找长度为:ASL=(IPL+n+EPL)/(n+n+1) = (2IPL+3n)/(2n+1)

由此可见,要使得二叉排序树具有最小的平均查找长度,应该使内路径长度达到最小。具有最短内路径长度的二叉排序树被称为最佳二叉排序树。可以证明,最佳二叉排序树的平均查找长度为O(log2 n)。

因此,具有n个结点的二叉排序树的平均查找长度与树的形态有关。最坏的情况下,二叉排序树退化为一棵单枝的二叉树,其平均查找长度为(n+1)/2,是O(n)量级,与顺序查找相同。