算法分析-第1关:求一组数据中最大的两个数(代码详解版)

任务描述

本关任务:利用分治法求一组数据中最大的两个数和最小的两个数。

编程要求

请在右侧编辑器Begin-End处补充代码,完成本关任务。

测试说明

平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:

测试输入:

  1. 10 //数据的总个数
  2. 1 //此行及以下为具体的每个数据
  3. 3
  4. 5
  5. 7
  6. 9
  7. 10
  8. 8
  9. 6
  10. 4
  11. 2

预期输出:

  1. max1=10 max2=9
  2. min1=1 min2=2

        接下来我讲一下思路!

        首先读题分治求解最大两个数和最小的树,那么思索之后,其实先排序是最好的

分治算法中有两种排序方法:

                快速排序法

                合并排序法

那么我先暂时用快速排序来解。(对于代码讲解比较细腻一些)

下面文字叙述(不够形象可以看一下b站

快速排序:

                  其实就是找一个值p作为基准(也就是比较的对象),然后通常用最左侧的值作为p值,

将左侧的值和右侧的值与p进行比较,

左>p,那么左就要放到右边。否则左边的指针向右移动。

右<p,那么右就要放到左边。否则右边的指针向左移动。

那么当左指向与右指向相同的时候,将p放在此处。

此时我们已经利用p分开了左右:

        左边一定是比p小的,右边一定是比p大的。

        那么接下来递归调用此函数,左半部分依旧按照上述步骤,右半部分也是按照上述步骤即可。

下面就看一下代码部分,详细标注在代码注释中

#include <stdio.h>
void quick_sort(int arr[], int l, int r); // 函数声明  

int main()
{
	int num,i;
    scanf("%d",&num);
    int a[num];            
    for(i=0;i<num;i++)
        scanf("%d",&a[i]);        
    /**********  Begin  **********/
    quick_sort(a,0,num-1);        #调用函数,数组直接a表示,左侧0,右侧num-1
    printf("max1=%d max2=%d\n",a[num-1],a[num-2]);    #最大则是右边两个
    printf("min1=%d min2=%d",a[0],a[1]);              #最小左侧两个


    /**********  End  **********/
}

void quick_sort(int arr[],int l,int r){        #写代码思路和书写顺序不大相同
    if(l>=r) return;                 #因为下面要递归调用,这里作为判断左边的数大于等于r就结束                                                                            
    int left=l,right=r;              #left和right作为指针,会发生变动,保留l和r的值。
    int p=arr[l];                    #将左侧给p
    while(left<right){               #循环直到不符合结束
        while(left<right && arr[right]>=p) --right;    #右侧的值大于p,指针左移一位,同时减         #                                                      #到与左指针相同的位置时结束
        if(arr[right]<p) arr[left] = arr[right];       #右侧值小于p,移动至左侧位置

        while(left<right && arr[left]<=p) ++left;        #同上
        if(arr[left]>p) arr[right] = arr[left];

        if(arr[left]>=arr[right]) arr[left]=p;        #指针指向统一位置,赋值给p
    }                                                 #此时完成一部分
    quick_sort(arr,l,right-1);                        #调用左侧,用到初始值l
    quick_sort(arr,right+1,r);                        #调用右侧,用到初始值r
}

1、为什么if(l>=r)

        因为当进行到最后一个的时候,不只是l在减1,r也在加,不一定会相等

2、最外层一个while有必要吗?

        问出这个问题,你可能还没理清楚,代码思路,或者出现了盲点。

        他不是只停了一次,换了位置结束了就,而是多次比较多次换位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值