查找:顺序查找、二分查找、分块查找

一、顺序查找

按索引顺序查找,可用于查找无序序列

int SequenceSearch(vector<int> seq, int key)
{
    const int c_len = seq.size();
    for(int i=0; i<c_len; ++i)
        if(seq[i] == key)
            return i;  // 找到key = seq[i]
    return -1;  // key不在表中,查找失败
}

时间复杂度:T(n) = θ(n)


二、二分查找

待查找序列必须有序

过程:

通过将待查找的值key与序列中位数比较,判断key在左半序列还是右半序列;然后在新的序列(左半序列或右半序列)中继续做二分查找,直到找到或序列查找完毕

int BinarySearch(vector<int> seq, int key)
{
    const int c_len = seq.size();
    int left = 0, right = c_len, middle;
    while(left < right)
    {
        middle = (left + right) / 2;
        if(seq[middle] == key)
            return middle;  // 找到key = seq[middle]
        else if(seq[middle] > key)
            right = middle;        // key 不会等于 seq[right]
            else if(seq[middle] < key)
                left = middle + 1;       //key 可能等于 seq[left]
    }
    return -1;  // key不在表中,查找失败
}

时间复杂度:while循环次数最大为lgn(向上取整)(以2为底)

                    T(n) <= lgn x 常数 = O(lgn)

三、分块查找

性能位于顺序查找和二分查找中间

除了存储待排序序列之外,还需要存储一个索引表(键为序列中的元素,对应的值为元素所在的块)

假设待排序序列有n个元素,将待排序序列分成k个块,每块中的元素为n/k+1(最后一块的元素小于等于n/k+1); 

这k个块总体是有序的,即第i块中的任意元素一定小于第i+1块中的任意元素;

每个块中的元素是无序的。

步骤:先找到待查找元素key的块索引,再在相应的块中查找key

由于k个块总体有序,所以可以使用顺序查找或者二分查找来查找块索引;

由于块中元素是无序的,所以只能通过顺序查找在相应块中查找key。

c++代码:

//在seq[p~q]中顺序查找key
int SequenceSearch1(vector<int> seq, int key, int p, int q);  // IndexSearch中使用

int BinarySearch1(vector<int> seq, int key);  // IndexSearch中使用

int IndexSearch(vector<int> seq, int key, const int k)
{
    const int c_len = seq.size();
    const int max_n = c_len / k + 1;
    map<int, int> block_table;  // black_min[i], block_index
    vector<int> block_min;
    for(int i=0; i<k; ++i)
       {
            block_table[seq[max_n*i]] = i;  // 为了方便,比第i块最小值大,比第i+1块最小值小的元素块索引为i
            block_min.push_back(seq[max_n*i]);  //为了方便,这里的seq排过序了,所以每块的最小值就是每个块的第一个元素
       }
    int min_index = BinarySearch1(block_min, key);
    if(min_index == -1)   // key<min(seq)
        return -1;
    else
    {
        int block_index = block_table[block_min[min_index]];
        int index_left = block_index*max_n;
        int index_right = index_left + max_n;
        if (index_right > c_len)
            index_right = c_len;
        return SequenceSearch1(seq, key, index_left, index_right);
    }
}
int SequenceSearch1(vector<int> seq, int key, int p, int q)
{
    for(int i=p; i<q; ++i)
        if(seq[i] == key)
            return i;
    return -1;
}
int BinarySearch1(vector<int> seq, int key)
{
    const int c_len = seq.size();
    int left = 0, right = c_len, middle;
    while(left < right)
    {
        middle = (left + right) / 2;
        if(seq[middle] <= key)
            if((seq[middle+1] > key) || (middle + 1 >= c_len))
                return middle;
            else
                left = middle + 1;
        else
            right = middle;
    }
    return -1;
}

时间复杂度:

若查找块索引时使用二分查找,则块索引的时间复杂度为θ(lgk)  (假设分成k块);若采用顺序查找,则块索引时间复杂度为θ(k)

在块中使用顺序查找的时间复杂度为θ(n/k)

所以T(n) = θ(n/k+lgk)  或θ(n/k+k) 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值