0
点赞
收藏
分享

微信扫一扫

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

书呆鱼 2022-04-23 阅读 76
算法
  • (一)问题描述

        设计算法实现在一个具有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 条评论