求数列中的第1~k小元素

  • (一)问题描述

        设计算法实现在一个具有n个互不相同元素的数组A[1……n]中找出所有前k个最小元素的问题,这里k不是常量,即它是输入数据的一部分。要求算法的时间复杂性为O(n)。

  • (二)具体要求

        输入的第一行是一个正整数m,表示测试例个数。接下来几行是m个测试例的数据,每个测试例的数据由三行组成,其中,第一行输入一个正整数n,表示元素的个数;第二行输入n个整数,整数之间用一个空格隔开。第三行输入一个正整数k,表示该组测试例中的前k个最小元素(设给出的每个整数序列中的元素是唯一的)。

  • (三)解题思路

  1. 首先把整个问题进行拆分,分成三个部分:录入数据、对一组数据元素进行升序排序、输出前k个元素->解决问题
  2. 排序:我使用的是希尔排序(这边复习一下希尔排序):

        举例如下一组数据含10个元素,起初是无序的。num=10代表元素个数,gap代表间隔几个数据进行比较。gap越大则大数和小数能更快的到达数据的两端,gap越小则比较并交换后的数据越接近有序(gap=1时,交换后的数据为最终需要的升序序列),一般取总元素个数的一半为初始gap。

                                                                                                     【位置发生变换的元素颜色改变】

  • (四)完整代码

#include <stdio.h>
int num[30];

//排序函数:希尔排序
void ShallSort(int m){
    for(int j=1;j<=m;j++){
        //获取数据元素并录入数组
        printf("请输入第%d个测试例的元素个数:",j);
        int n;
        scanf("%d",&n);
        int i;
        printf("请输入%d个元素(请用空格隔开):",n);
        for(i=0;i<n;i++){
            scanf("%d",&num[i]);
        }
//        测试元素录入情况
//        for(int j=0;j<n;j++){
//            printf("%3d",num[j]);
//        }
        
        //对数组内元素进行希尔排序
        int gap = n;
        while (gap > 1) {
            gap/=2;
            int i;
            //开始其中一次排序
            for(i=0;i<n-gap;i++){
                int end = i;
                int tmp = num[end+gap];
                while (end>=0) {
                    if(tmp<num[end]){
                        num[end+gap] = num[end];
                        end -= gap;
                    }
                    else{
                        break;
                    }
                }
                num[end+gap] = tmp;
            }
        }
        printf("请输入需要前几个元素:");
        int k;
        scanf("%d",&k);
        for(int i=0;i<k;i++){
            printf("%3d",num[i]);
        }
        printf("\n");
    }
}

int main(){
    int m;
    printf("请输入测试例个数:");
    scanf("%d",&m);
    //获取录入元素并排序
    ShallSort(m);
    
    return 0;
}

  • (五)测试及结果

 

  • (六)总结

        本题还是简单的问题,问题变得复杂的时候,分治能发挥的作用真的很大,感觉写代码的时候,尽量让main函数保持精简,别的内容都“外包”给其他的函数,这样代码也更加清晰。在写的时候本来打算把排序和输出分到两个函数里,但是有点转不过弯来,最后还是写在一起了。有大佬可以实现分到两个函数的话,可以给我讲讲吗,感谢感谢。

        然后,果然很大一部分思路还是得看前辈大佬的。学习之路漫漫啊……

        谨以博客记录我的学习,复盘什么的。(咸鱼瘫)终于搞完了这篇。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悦崽在线搬砖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值