数据结构学习笔记(10)---基于线性表的查找

本文详细介绍了顺序查找、折半查找及块查找三种经典查找算法的原理与实现过程,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)顺序查找

顺序查找比较简单,其思路就是从顺序表的头部或者尾部依次查找数组,直到查找数值为止。其平均查找长度为:ASL = (n+1)/2
代码如下:

int SearchByIndex(int* arr,int length,int key)
{
    while (-1 != --length)
    {
        if (key == arr[length])
        {
            return length;
        }
    }
    return length;
}
(2)折半查找

思路:折半查找的前提条件是该顺序表必须是有序的,先取该数组的中间值进行比较,如果大于该值则说明要查找的数值肯定是在其右边,如果小于该值说明查找的值肯定在其左边,依次循环下去,可定会找到存在的值。其平均查找长度为:ASL = log2(n+1)-1
代码如下:

int Search_Bin(int* arr, int length, int key)
{
    int low = 0, high = length - 1,mid = (high + low) / 2;
    while (low<=high)
    {
        if (key == arr[mid])
        {
            return mid;
        }
        else if (key < arr[mid])
        {
            high = mid - 1;
            mid = (high + low) / 2;
        }
        else
        {
            low  = mid + 1;
            mid = (high + low) / 2;
        }
    }
    cout << "不存在" << endl;
    return -1;
}
(3)块查找

思路:分块查找要求把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。假设是按关键码值非递减的,那么这种块与块之间必须满足已排序要求,实际上就是对于任意的i,第i块中的所有节点的关键码值都必须小于第i+1块中的所有节点的关键码值。此外,还要建立一个索引表,把每块中的最大关键码值作为索引表的关键码值,按块的顺序存放到一个辅助数组中,显然这个辅助数组是按关键码值费递减排序的。查找时,首先在索引表中进行查找,确定要找的节点所在的块。由于索引表是排序的,因此,对索引表的查找可以采用顺序查找或折半查找;然后,在相应的块中采用顺序查找,即可找到对应的节点。平均查找长度 ASL = Lb + Lw;Lb是查找索引表中关键字的平均查找长度Lb 与 查找每一块顺序查找的平均查找长度 Lw,因此ASL = log2(n/s+1) + s /2 ;
百度百科
实现代码:

struct index /*定义块的结构*/
{
    int key;
    int start;
    int end;
} index_table[16]; /*定义结构体数组*/
int block_search(int key, int a[]) /*自定义实现分块查找*/
{
    int i, j;
    i = 1;
    while (i <= 3 && key > index_table[i].key) /*确定在那个块中*/
        i++;
    if (i > 3) /*大于分得的块数,则返回0*/
        return 0;
    j = index_table[i].start; /*j等于块范围的起始值*/
    while (j <= index_table[i].end && a[j] != key) /*在确定的块内进行查找*/
        j++;
    if (j > index_table[i].end) /*如果大于块范围的结束值,则说明没有要查找的数,j置0*/
        j = 0;
    return j;
}
void Creat()
{
    int i, j = 0, k, key, a[16];
    cout<<"please input the number:\n";
    for (i = 1; i < 16; i++)
        cin>>a[i]; /*输入由小到大的15个数*/
    for (i = 1; i <= 3; i++)
    {
        index_table[i].start = j + 1; /*确定每个块范围的起始值*/
        j = j + 1;
        index_table[i].end = j + 4; /*确定每个块范围的结束值*/
        j = j + 4;
        index_table[i].key = a[j]; /*确定每个块范围中元素的最大值*/
    }
    cout<<"please input the number which do you want to search:\n";
    cin>>key; /*输入要查询的数值*/
    k = block_search(key, a); /*调用函数进行查找*/
    if (k != 0)
        cout<<k; /*如果找到该数,则输出其位置*/
    else
        cout <<"no found!"; /*若未找到则输出提示信息*/
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值