查找、二叉排序树

顺序查找

顺序查找又叫线性查找,是最基本的查找技术,它的查找过程是:从表中第一个记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果知道最后一个记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功。

顺序查找算法实现代码如下:

/*顺序查找,a为数组,n为要查找的数组个数,key为要查找的关键字*/
int Sequential_Search(int *a,int n,int key)
{
    int i;
    for(i=1;i<=n;i++)
    {
        if(a[i] == key)
            return i;
    }
    return 0;
}

代码很简单,就是在数组a中查看有没有关键字(key),当你需要查找复杂表结构的记录时,只需要把数组a与关键字key定义成你需要的表结构和数据类型即可。

这里并不够完美,因为每次循环时都需要对i是否越界做判断,事实上,还可以有更好一点的办法,设置一个哨兵,可以解决不需要每次让i与n做判断,实现代码如下:

int Sequential_Search(int *a,int n,int key)
{
    int i;
    a[0] = key;/*设置a[0]为关键字值,我们称之为‘哨兵’*/
    i = n;  /*循环从尾部开始*/
    while(a[i] != key)
    {
        i--;
    }
    return i;
}

此时代码是从尾部开始查找,由于a[0]=key,也就是说,如果a[i]中有key则返回i,查找成功。否则一定在最终的a[0]处等于key,此时返回0,即说明a[1]~a[n]中没有关键字key,查找失败。

折半查找

折半查找(Binary Search)技术,又称为二分查找。它的前提线性表中的记录必须是关键码有序,线性表必须采用顺序存储。折半查找的基本思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找,不断重复上面过程,知道查找成功,或所有查找区域无记录,查找失败为止。实现代码如下:

int Sequential_Search(int *a,int n,int key)
{
    int low,high,mid;
    low = 1;
    high = n;
    while(low <=high)
    {
        mid = (low+high)/2;
        if(key < a[mid])
            high = mid - 1;
        else if(key >a[mid])
            low = mid + 1;
        else
            return mid;
    }
    return 0;
}

二叉排序树(Binary Sort Tree),又称为二叉查找树,它或者是一颗空树,或者具有下列性质的二叉树。

若它的左子树不为空,则左子树所有结点的值均小于它的根结点的值。

若它的右子树不为空,则右子树上所有结点的值均不大于根结点的值。

它的左,右子树也分别为二叉树。

二叉树的结构:

typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild;
} BiTNode , *BiTree;

二叉排序树的查找实现过程代码如下:

/**递归查找二叉树T中是否存在key,
指针f指向T的双亲,其初始调用值为NULL
若查找成功,则指针p指向数据元素结点,并返回TRUE,
否则指针p指向查找路径上访问的最后一个结点并返回FALSE
*/
Status SearchBST(BiTree T ,int key, BiTree f, BiTree *p)
{
    if(!T)
    {
        *p = f;
        return FALSE;
    }
    else if(key == T->data)
    {
        *p = T;
        return TRUE;
    }
    else if(key < T->data)
        return SearchBST(T->lchild,key,T,p);
    else	return SearchBST(T->rchild,key,T,p);
}

二叉排序树的插入操作

代码如下:

/**当二叉排序树T中不存在关键字等于key的数据元素时,
插入key并返回TRUE,否则返回FALSE
*/
Status InsertBST(BiTree *T,int key)
{
    BiTree p,s;
    if(!SearchBST(*T,key,NULL,&p))
    {
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        if(!p)
        {
            *T = s;
        }
        else if(key < p->data)
            p->lchild = s;
        else
            p->rchild = s;
        return TRUE;
    }
    else
        return FALSE;
}

二叉树的删除操作:

对二叉树结点的删除分三种情况:

叶子结点

仅有左或右子树

左右子树都有的结点。

我们来看代码,下面这个算法是递归方式对二叉树排序树T查找key,查找到并删除代码:

/**若二叉树T中存在关键字等于key的数据元素时,则删除该数据元素结点,
并返回TRUE,否则返回FALSE
*/
Status DeleteBST(BiTree *T,int key)
{
    if(!*T)
        return FALSE;
    else
    {
        if(key == (*T)->data)
            return Delete(T);
        else if(key < (*T)->data)
            return DeleteBST(&(*T)->lchild,key);
        else	
            return DeleteBST(&(*T)->rchild,key);
    }
}

Status Delete(BiTree *p)
{
    BiTree q,p;
    if((*p)->rchild == NULL)
    {
        q=*p;*p=(*p)->lchild;free(q);
    }
    else if((*p)->lchild == NULL)
    {
        q = *p; *p = (*p)->rchild;free(q);
    }
    else
    {
        q = *p;s = (*p)->lchild;
        while(s->rchild)
        {
            q = s;s = s->rchild;
        }
        (*p)->data = s->data;
        if(q!=*p)
            q->rchild = s->lchild;
        else
            q->lchild = s->lchild;
        free(s);
    }
    return TRUE;
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/sanmao0816/article/details/41213189
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞