二分查找、三分查找 “朝闻道”知识分享大赛

菜菜菜攻城狮 2023-12-31 15:42:42

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

 

二分查找与三分查找:确定键值mid,mid为最左下标+最右下标的和除以2,将k与A[MID]进行比对,相等时输出结果,不相等时比较大小,判断在前半部分还是后半部分,并再次对此部分进行折半查找,当没有找到对应k时,我们通过l下标去比对其附近的值和k的值,找到其最接近的值返回。三分查找思路与二分查找相似,不同点在于键值k有2个,所以对于较大数组效率会好于二分查找。若查找元素不在数组中,需要返回最接近元素,其思路和二分查找一致。查找次数为查找键与数组元素的比较次数。

//顺序查找
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;
}

//折半
int BinarySearch(int k,int &comparisons){

    int l=0,r=n-1,mid;
    while(l<r){
        mid=(l+r)/2;
        //cout<<mid<<endl;
        comparisons++;
        if(arr[mid]==k) return mid;
        else if(arr[mid]>k){
            r=mid-1;
        }
        else {
            l=mid+1;
        }
    }

    //cout<<"l"<<l<<endl;
    //cout<<"r"<<r<<endl;
    // 元素不在数组中,返回最接近的元素位置
    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;

         //通过l指针,如果l位置的数大于k则比较l和l-1位置的值
        //否则比较l和l+1的值即可

        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;
}

// 三分查找
int TernarySearch(int k,int &comparisons) {
    int l=0,r=n-1,mid1,mid2;

    while (l <= r) {
        int mid1 = l + (r - l) / 3;
        int mid2 = r - (r - l) / 3;

        //cout<<"mid1"<<mid1<<endl;
        //cout<<"mid2"<<mid2<<endl;

        comparisons++;
        if (arr[mid1] == k) {
            return mid1;
        }


        comparisons++;
        if (arr[mid2] == k) {
            return mid2;
        }


        comparisons++;
        if (k < arr[mid1]) {
            r = mid1 - 1;
        } else if (k > arr[mid2]) {
            l = mid2 + 1;
        } else {
            l = mid1 + 1;
            r = mid2 - 1;
        }
    }


     if (r < 0) {
        return l;
    } else if (l >= n) {
        return r;
    } else {
        // 找到最接近的元素位置


        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;
}

 

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

857

社区成员

发帖
与我相关
我的任务
社区描述
中南民族大学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创作助手写篇文章吧