二分查找、二叉搜索树

二分查找

在有序数组中,要搜索元素x,先把v与中间位置的元素进行比较,如果x较小,那么x必定在数组的前半部分;如果x较大,那么x必定在数组的后半部分。

int arr[];
...

int bsearch(int left,int right, int x) {
    if(left>right) return -1;
    int mid = 0;

    //注意是<=
    while (left <= right) 
    {
        mid = (right-left)/2 + left; // 防止溢出
        if (arr[mid] == x)
            return mid;
        else if (arr[mid] < x)
            left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}

在一次查找中,无论有没有找到,二分查找使用不超过[lgN]+1次的比较。

二叉搜索树(BST)

定义:二叉搜索树(BST)是一棵二叉树,它的每个内部节点都关联一个关键字,并具有以下性质:任意节点的关键字大于等于该节点左子树中所有节点的关键字,小于等于该节点右子树中所有节点的关键字。

BST的搜索和插入操作的实现为

Item searchR(link h,Key v)
{
    Key t=key(h->item);
    if(h==z return NULLitem;//z表示空树
    if eq(v,t) return h->item;
    if less(v,t) return searchR(h->l,v);
        else return searchR(h->r,v);
}
Item STsearch(Key v)//此函数递归调用searchR函数
{return searchR(head,v);}//head指向根节点

link insertR(link h,Item item)
{
    Key v=key(item),t=key(h->item);
    if(h==z) return NEW(item,z,z,1);//NEW是构造新节点的函数。当树为空时,构造根节点,指向左右两个空树,树的大小为1
    if(less(v,t)//若待插入元素的关键字小于h的关键字
        h->l=insertR(h->l,item);
    else h->r=insertR(h->r,item);
    (h->N)++;//树的总大小加1
    return h;   
}
void STinsert(Item item)//递归调用insertR函数
{head=insertR(head,item);}

程序中,搜索函数和二分搜索的思路基本一样。BST的基本特征是插入实现和搜索实现一样简单。递归函数insertR的思路是:如果树为空,就返回包含数据项的一个新节点;如果待插入关键字小于根节点的关键字,把新节点插入到左子树,并使左链接指向它;否则把它插入到右子树,并使右链接指向它。
另外,对BST的排序操作可以用中序遍历实现。

基于旋转操作的BST中的根插入

左旋转
左旋转把右孩子节点及其右子树提升一层,同时把根节点及其左子树下移一层:把原根节点作为原右孩子节点(新的根节点)的左节点,并把原右孩子节点的左子树作为其新的右子树。
《二分查找、二叉搜索树》

//返回新的根节点,也就是旋转后的原右孩子节点
link rotL(link h)
{
    link x=h->r;
    h->r=x->l;
    x->l=h;
    return x;
}

右旋转
把左孩子节点及其左子树提升一层,同时把根节点及其右子树下移一层:把原根节点作为原左孩子节点(新的根节点)的右节点,并把原左孩子节点的右子树作为原根节点新的左子树。
《二分查找、二叉搜索树》

//返回新的根节点,也就是旋转后的原左孩子节点
link rotR(link h)
{
    link x=h->l;
    h->l=x->r;
    x->r=h;
    return x;
}

利用旋转操作,可以在BST中递归地将一个新节点插入到根节点。

link insertT(link h,Item item)
{
    Key v=key(item);
    if(h==z) return NEW(item,z,z,1);//如果树是空的,直接构造根节点
    if(less(v,key(h->item)))
        {h->l=insertT(h->l,item);h=rotR(h);}//递归进行插入,并通过旋转把新节点移到根节点的位置
    else
        {h->r=insertT(h->r,item);h=rotL(h);}
    return h;
}
void STinsert(Item item)
{head=insertT(head,item);}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/jinzhao1993/article/details/50492601
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞