先升后降数组确定最大值 “朝闻道”知识分享大赛

菜菜菜攻城狮 2023-12-31 15:47:37

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

 

给定先升后降(或先降后升)数组,使用二分检索思路和三分检索思路查找该数组的最大值(或最小值),并统计关键字比较的次数。

先升后降数组确定最大值:确定键值K,比较k前一项元素与k后一项元素与k的关系,有以下几种不同情况:当A[K]>A[k+1]并且A[K]>A[K-1]时,K即为最大值,A[K]>A[k+1]且A[K]<A[k-1]时,前一部分中有最大值,后一部分不会有最大值。A[K]<A[k+1]且A[K]>A[k-1]时最大值必然在后一部分。比较次数为键值与元素的比较次数和。

//折半查找最大,处理先升后降数组
int BinarySearch1(int &comparisons){

    int l=0,r=n-1,mid;
    while(l<r){

        //cout<<"l:"<<l<<endl;
        //cout<<"r:"<<r<<endl;
        mid=(l+r)/2;
        comparisons++;
        if(arr[mid]<arr[mid+1]){

            //说明最大在右侧
            l=mid+1;
        }else if(arr[mid]>arr[mid+1]){
            //说明最大在左侧,但不能排除当前mid位置的元素
            r=mid;
        }
    }

    return l;
}


//三分检索查找最大,处理先升后降数组
int TernarySearch1(int &comparisons){

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

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

        //cout<<"l:"<<l<<endl;
        //cout<<"r:"<<r<<endl;

        comparisons++;
         if (arr[mid1] > arr[mid1 + 1]) {
            //在第一区域
            r = mid1;
        } else if (arr[mid2] > arr[mid2 - 1]) {
            //在第三区域
            l = mid2 ;
        } else {
            //在第二区域
            l = mid1 + 1;
            r = mid2;
        }
    }

    return l;
}

//使用二分检索思路和三分检索思路查找该数组的最大值(或最小值)
void question6(){
    //首先将arr变为先升序后降序
    ascAndDesc();

    cout<<"排序之后的数组:";
    for(int i=0;i<n;i++){
        cout<<arr[i]<<"\t";
    }
    cout<<endl;

    int count[2]={0};

    int res1=BinarySearch1(count[0]);
    cout<<"二分检索   下标为:"<<res1<<",值为:"<<arr[res1]<<",比较次数:"<<count[0]<<endl;

    int res2=TernarySearch1(count[1]);
    cout<<"三分检索   下标为:"<<res2<<",值为:"<<arr[res2]<<",比较次数:"<<count[1]<<endl;

}

预排序查找数组中第k个最小元素:采用任意一种排序算法将原数组升序排序,直接输出第k个元素即为所需的第k个最小元素,关键字比较次数为1。

int PreSortedKthSmallest(int k, int &comparisons){

    int *a=(int*)malloc(n*sizeof(int));
    for(int i=0;i<n;i++){
        a[i]=arr1[i];
    }

    //先进行排序
    for(int i=0;i<n-1;i++){
        for(int j=0;j<n-1;j++){
            comparisons++;
            if(a[j]>a[j+1]){
                //交换
                int temp=a[j+1];
                a[j+1]=a[j];
                a[j]=temp;
            }
        }
    }

    return a[k-1];
}

 

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

858

社区成员

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