寻找数组N中最大(最小的)M个数(亲自调试可运行)

当N很小十可以使用方法2,

当N很大时可以使用方法1,从硬盘逐次读入解决;

/*方法 1  适合大量数据

*寻找长为N的数组的前M大的元素并输出。

*用堆的性质,使用数组N建立一个M大的最大堆,然后输出堆内容即可

*时间复杂度分析:  建堆时间O(M)

*遍历数字,并在堆中比较时间O((N-M)logM)

*总时间复杂度O(M)+ O((N-M)logM)

*

*空间复杂度 O(M)

*/

/*方法2

*使用类快速排序方法解决,“适合较少数据”

*

*时间复杂度O(N)

*

*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NDEBUG
#include <assert.h>

int  input(void);
void print(int * p,int len);
void adjust(int *heap,int heap_size,int index);
void swap(int *a,int *b);
void built_heap(int *heap,int heap_size,int *a);
void find_max(int *heap,int heap_size,int *a,int len);
//方法2
void  quick_find(int *arry,int len, int M);
int partation(int *arry,int len,int start,int end);

int main(void)
{
  int heap_size;
  int *heap;
  //int a[]={23,54,47,12,6,23,14,1,25,3,5,4,9};
  int a[]={1,231,45,69,78,15,36,49,14,36,24,15,89,12,11,69,122,192,126,2125,1,12,4548,125,4755,232,            5,26,24,25,22,22,66,214,1235,2,332,56,66,662,552,225,226,226,2262,262,626,2626,2626,789,         622,15,25,262,551,789,781,895,895,9511,942,412,233,203,202,30,95,2,31,22,12,23,325,235,266,45678,15629,7894};
  heap_size=input();
  heap=(int *)malloc(sizeof(int)*heap_size);
  find_max(heap,heap_size,a,sizeof(a)/sizeof(int));
  print(heap,heap_size);
  free(heap);
  quick_find(a,sizeof(a)/sizeof(int), heap_size);
  return 0;
} 

void print(int * p,int len)
{
    int i;
    for(i=0;i<len;i++)
      printf("%d  ",p[i]);
      printf("\n");
    return;
}

int  input(void)
{
    int m;
    printf("input the M:");
    scanf("%d",&m);
    return m;
}

//建立堆
void built_heap(int *heap,int heap_size,int *a)
{
    int i;
    assert(heap!=NULL&&a!=NULL);
    for(i=0;i<heap_size;i++)
         heap[i]=a[i];
    for(i=(heap_size>>1);i>=0;i--)
       adjust(heap,heap_size,i);
    return;
}
//堆调整
void adjust(int *heap,int heap_size,int index)
{
   int left=(index<<1)+1;
   int right=(index<<1)+2;
   int parent=index;
   assert(heap!=NULL);
   if(left<heap_size&&heap[left]<heap[parent])
            parent=left;
   if(right<heap_size&&heap[right]<heap[parent])
            parent=right;
   if(parent!=index)
     {
        swap(&heap[parent],&heap[index]);
        adjust(heap,heap_size,parent);
     }
    return;
} 

void swap(int *a,int *b)
{
    *a=*a^*b;
    *b=*a^*b;
    *a=*a^*b;
}

void find_max(int *heap,int heap_size,int *a,int len)
{
     int i;
     int j;
     assert(heap!=NULL&a!=NULL);
     if(heap_size>=len)
     return;
     built_heap(heap,heap_size,a);
     for(i=heap_size;i<len;i++)
     {
         if(a[i]>heap[0])
            {
               heap[0]=a[i];
               adjust(heap,heap_size,0);
            }
     }
     return;
}
//方法2
void  quick_find(int *arry,int len, int M)
{
     int start=0;
     int end=len-1;
     int count=M-1;
     int i;
     int proe;
     if(arry==NULL||len<M)
     return;
     proe=partation(arry,len-1,start,end);
     while(proe!=count)
     {
         if(proe>count)
            proe=partation(arry,len-1,start,proe-1);
         else
            proe=partation(arry,len-1,proe+1,end);
     }
     for(i=0;i<M;i++)
     printf("%d  ",arry[i]);
     printf("\n");

}
int partation(int *arry,int len,int start,int end)
{
     int key=arry[start];
     while(start<end)
     {
          while(start<end&&arry[end]<=key)
               end--;
           if(start<end)
              arry[start++]=arry[end];
          while(start<end&&arry[start]>key)
              start++;
          if(start<end)
             arry[end--]=arry[start];
     }
     arry[start]=key;
     return start;
}

程序运行结果:

“输出两行分别为方法1和方法2结果”

[[email protected] code_test]$ gcc   -o arryN_maxM arryN_maxM.c
[[email protected] code_test]$ ./arryN_maxM
input the M:10
2125  2262  2626  4755  2626  45678  9511  7894  15629  4548
45678  15629  9511  7894  4548  2626  2626  4755  2262  2125 
时间: 2024-10-29 19:06:59

寻找数组N中最大(最小的)M个数(亲自调试可运行)的相关文章

第2章 数字之魅——寻找数组中的最大值和最小值

寻找数组中的最大值和最小值 问题描述 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? 分析与解法 [解法一] 可以把寻找数组中的最大值和最小值看成是两个独立的问题,我们只要分别求出数组的最大值和最小值即可解决问题.最直接的做法是先扫描一遍数组,找出最大的数以及最小的数.这样,我们需要比较2*(N-1)次才能找出最大的数和最小的数.代码如下: 1 package chapter2shuzizhimei.findminmax; 2 /** 3 * 寻找数组中的最大值和最小

找到无序数组中最小的k个数

题目:给定一个无序整数数组arr,找到其中最小的k个数 要求:如果数组arr的长度为n,排序之后自然可以得到最小的k个数,此时时间复杂度与排序的时间复杂度相同均为O(NlogN),本题要求实现时间复杂度为O(NLogK). 1.O(NLogK)的方法,即一直维护一个有k个数的最大的大根堆,这个堆是目前选出的k个最小数,在堆里的k个元素中堆顶的元素是最大的一个. 接下来遍历整个数组,遍历的过程中看当前数是否比堆顶元素小.如果是,就把堆顶的元素替换成当前的数,然后从堆顶的位置调整堆,替换后堆的最大元

【编程之美】寻找数组中的最大值和最小值

数组是最简单的一种数据结构.我们经常碰到的一个基本问题,就是寻找整个数组中最大的数,或者最小的数.这时,我们都会扫描一遍数组,把最大(最小)的数找出来.如果我们需要同时找出最大和最小的数呢? 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? 分析与解法 解法一:分别求最大和最小值 可以分别求出数组的最大值和最小值,这样,我们需要比较2N次才能求解. 解法二:分组求解 (1) 按顺序将数组中相邻的两个数分在同一组: (2) 比较同一组的两个数,将大的数放在偶数位上,小的放

数字之魅:寻找数组中的最大值和最小值

数组是最简单的一种数据结构.我们经常碰到的一个基本问题,就是寻找整个数组中最大的数,或者最小的数.这时,我们都会扫描一遍数组,把最大(最小)的数找出来.如果我们需要同时找出最大和最小的数呢? 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? 这个题目比价简单,主要方案如下: 方案一:分别求最大和最小值.这是一种比较常规的解法.可以分别求出数组的最大值和最小值,这样,我们可以采用最基本的冒泡思想遍历两次(2N)就能求解. 方案二:分组求解.由于前面的需要遍历2N次.这里为

【编程题目】旋转数组中的最小元素☆

69.旋转数组中的最小元素(数组.算法).题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为 1. 我就用了最简单的方法.而且开始还没考虑1, 0, 1 ,1这样的情况 /* 69.旋转数组中的最小元素(数组.算法). 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个 排好序的数组的一个旋转

[经典算法题]寻找数组中第K大的数的方法总结

[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,当然,解决这个问题的方法很多,本人在网上搜索了一番,查找到以下的方式,决定很好,推荐给大家. 所谓"第(前)k大数问题"指的是在长度为n(n>=k)的乱序数组中S找出从大到小顺序的第(前)k个数的问题.

2.10 用最少次数寻找数组中的最大值和最小值[find min max of array]

[本文链接] http://www.cnblogs.com/hellogiser/p/find-min-max-of-array.html [题目] 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? [分析] 1. 遍历两次数组,分别找出最大值和最小值,需要进行 2N 次比较. 2. 将数组中的元素分组,按顺序将数组中相邻的两个数分在同一组,用Max和Min来存储最大值和最小值.同一组比较完之后,较小的数与当前的最小值比较,如该数小于当前最小值,更新Min:较大的数与当

小米笔试题:无序数组中最小的k个数

题目描述 链接:https://www.nowcoder.com/questionTerminal/ec2575fb877d41c9a33d9bab2694ba47?source=relative 来源:牛客网 无序数组中最小的k个数 对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数,顺序与原数组中元素顺序一致. 给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数. 测试样例: [1,2,4,3],4,2 返回:[1,2] 代码 需要保留K个较小的元素,可以删

Magic Index 寻找数组中A[i]=i的位置(原题转自微信号待字闺中)

有一个有意思的题目叫做Magic Index:给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i.假设A中的元素递增有序.且不重复,请给出方法,找到这个Magic Index.更进一步,当A中允许有重复的元素,该怎么办呢? 一般情况下这种题目一看没有多复杂的时间复杂度,直接扫描一边数组就好了,O(n),当我们认识读题目的时候发现有个体检没有用到就是这个“数组元素递增有序,不重复”,这句话会不会给我们带来捷径呢,事实是可以的.通常