顺序查找、插值查找 “朝闻道”知识分享大赛

菜菜菜攻城狮 2023-12-31 15:45:13

这是我参加“朝闻道”知识分享大赛的第六十篇文章。

 

顺序查找:按照数组顺序一个一个的比对查找,找到时返回下标,无法找到时返回最后一个位置,在问题5中的顺序查找中,我们并不是返回最后的位置的。当找到了比k大的元素还未返回值时,我们就对这个元素和其上一个元素分别与k进行比对,得到绝对差值最小的那一个,用于输出最接近的值。查找次数为查找元素与数组元素的比较次数。

//顺序查找
int SequentialSearch(int k, int &comparisons) {
    for (int i = 0; i < n; ++i) {
        ++comparisons;
        if (arr[i] == k) {
            return i;
        } else if (arr[i] > k) {
            // 元素不在数组中,返回最接近的元素位置
            if (i == 0) {
                return i;
            } else {
                //检查前一个元素是否更加接近
                return (k - arr[i-1] <= arr[i] - k) ? i-1 : i;
            }
        }
    }

    // 元素不在数组中,返回最后一个位置
    return n - 1;
}

插值查找:将值与下标视作一xy坐标轴,确定k的值只需要用求直线坐标的方法确定即可确定pos的值,这样可使得pos的值较大概率的接近,若查找元素不在数组中,需要返回最接近元素,其思路和二分查找一致。查找次数为pos值与数组元素的比较次数。

// 插值查找
int InterpolationSearch(int k, int &comparisons) {
    int l = 0, r = n - 1;
    while (l <= r && arr[l] <= k && arr[r] >= k) {

        if (l == r) {
            if (arr[l] == k) return l;
            else return -1;
        }

        // 插值公式
        int pos = l + ((double)(r - l) / (arr[r] - arr[l])) * (k - arr[l]);

        // 调整搜索范围
        comparisons++;
        //cout<<"pos:"<<pos<<endl;
        if (arr[pos] == k) return pos;
        else if (arr[pos] < k) l = pos + 1;
        else r = pos - 1;
    }

    // 元素不在数组中,返回最接近的元素位置
    if (r < 0) return l;
    else if (l >= n) return r;
    else {
        // 找到最接近的元素位置

        //cout<<"k - arr[l-1]:"<<k - arr[l-1]<<endl;
        //cout<<"arr[l] - k:"<<arr[l] - k<<endl;
         if(arr[l]>k){
            if ( k - arr[l-1] <= arr[l] - k) {
                return l-1;
            } else {
                return l; // 否则返回当前位置 l
            }
        }else{
            if ( k - arr[l] <= arr[l+1] - k) {
                return l;
            } else {
                return l+1; // 否则返回当前位置 l
            }
        }
    }

    return -1;
}

蛮力法查找数组中第k个最小元素:在循环中,将数组中找到的最小值赋值为-1,用一个count记录比较次数直到到k就停止循环。最后返回其元素的值即可。

//查找第k个最小元素,蛮力法
int BruteForceKthSmallest(int k, int &comparisons){
    int *a=(int*)malloc(n*sizeof(int));
    for(int i=0;i<n;i++){
        a[i]=arr1[i];
    }

    int count=0,min=100;
    int len =n;

    while(count<k){
        min=100;
        int x=0;    //记录最小元素的下标
        int i=0;
        for(i;i<len;i++){
            comparisons++;
            if(a[i]<min&&a[i]>=0){
                min=a[i];
                x=i;
            }

        }
        a[x]=-1;  //暂时将已经找到的最小值赋值为-1
        count++;
    }
    return min;
}

 

...全文
189 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

976

社区成员

发帖
与我相关
我的任务
社区描述
中南民族大学CSDN高校俱乐部聚焦校内IT技术爱好者,通过构建系统化的内容和运营体系,旨在将中南民族大学CSDN社区变成校内最大的技术交流沟通平台。
经验分享 高校 湖北省·武汉市
社区管理员
  • c_university_1575
  • WhiteGlint666
  • wzh_scuec
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

欢迎各位加入中南民族大学&&CSDN高校俱乐部社区(官方QQ群:908527260),成为CSDN高校俱乐部的成员具体步骤(必填),填写如下表单,表单链接如下:
人才储备数据库及线上礼品发放表单邀请人吴钟昊:https://ddz.red/CSDN
CSDN高校俱乐部是给大家提供技术分享交流的平台,会不定期的给大家分享CSDN方面的相关比赛以及活动或实习报名链接,希望大家一起努力加油!共同建设中南民族大学良好的技术知识分享社区。

注意:

1.社区成员不得在社区发布违反社会主义核心价值观的言论。

2.社区成员不得在社区内谈及政治敏感话题。

3.该社区为知识分享的平台,可以相互探讨、交流学习经验,尽量不在社区谈论其他无关话题。

试试用AI创作助手写篇文章吧