转自http://blog.csdn.net/jiangyi711/archive/2010/03/08/5358185.aspx

输入n个数,找出其中最小的k个。
一般的思路是将这n个数排序,排在最前面的k个数就是答案。这种方法最快时间复杂度为nlog(n)。
如果再开辟一个长度为k的数组。以此读取这n个数,如果k数组没有满,则直接放入k数组中,如果满了,且当前的数比k数组中最大的数要小,那么就用当前的数替换k数组中最大的数。(实际上,k数组是一个大顶堆)。这样,当n个数读取完之后,k数组中就是最小的k个数。这时候的复杂度为nlog(k)。
然后将k数组排序,复杂度为klog(k)。

于是,总的复杂度为(n+k)log(k),书上为n+nlog(k),由于k通常比n小很多,所以这种方法比较快

 

  1. #include <cstdlib>     
  2. #include <cstdio>     
  3. #include <algorithm>     
  4. #include <cstring>     
  5. void get_k_Min(int array[], int k, int length) {     
  6.     int *heap = (int*)malloc(sizeof(int)*(k+1));     
  7.     memset(heap, 0, sizeof(int)*(k+1));     
  8.     for (int i=1; i<=length; ++i)     
  9.         if (i <= k) {     
  10.             heap[i] = array[i-1];     
  11.             int j = i;     
  12.             while (j > 1 && heap[j] > heap[j/2]) {                     
  13.                 heap[j]   = heap[j] + heap[j/2];     
  14.                 heap[j/2] = heap[j] - heap[j/2];     
  15.                 heap[j]   = heap[j] - heap[j/2];     
  16.                 j = j/2;     
  17.             }     
  18.         }     
  19.         else {     
  20.             if (heap[1] > array[i-1]) {     
  21.                 heap[1] = array[i-1];     
  22.                 int j = 1;     
  23.                 while (2*j <= k) {     
  24.                     int idx = 0;     
  25.                     if (2*j == k)     
  26.                         idx = 2*j;       
  27.                     else if (heap[2*j] > heap[2*j+1])     
  28.                         idx = 2*j;     
  29.                     else    
  30.                         idx = 2*j + 1;     
  31.                     if (heap[j] < heap[idx]) {     
  32.                         heap[j]   = heap[j] + heap[idx];     
  33.                         heap[idx] = heap[j] - heap[idx];     
  34.                         heap[j]   = heap[j] - heap[idx];     
  35.                     }     
  36.                     else    
  37.                         break;     
  38.                     j = idx;     
  39.                 }     
  40.             }     
  41.         }     
  42.     for (int i=k; i>1; --i) {     
  43.         heap[i] = heap[i] + heap[1];     
  44.         heap[1] = heap[i] - heap[1];     
  45.         heap[i] = heap[i] - heap[1];     
  46.         int j = 1;     
  47.         while (2*j <= i-1) {     
  48.             int idx = 0;     
  49.             if (2*j == i-1)     
  50.                 idx = 2*j;       
  51.             else if (heap[2*j] > heap[2*j+1])     
  52.                 idx = 2*j;     
  53.             else    
  54.                 idx = 2*j + 1;     
  55.             if (heap[j] < heap[idx]) {     
  56.                 heap[j]   = heap[j] + heap[idx];     
  57.                 heap[idx] = heap[j] - heap[idx];     
  58.                 heap[j]   = heap[j] - heap[idx];     
  59.             }     
  60.             else    
  61.                 break;     
  62.             j = idx;     
  63.         }     
  64.     }     
  65.     for (int i=1; i<=k; ++i)     
  66.         printf("%d ", heap[i]);     
  67.     free(heap);     
  68.     heap = NULL;     
  69.     printf("\n");     
  70. }     
  71. int main() {     
  72.     int array[] = {8,7,6,5,4,3,2,1};     
  73.     get_k_Min(array, 4, sizeof(array)/sizeof(int));      
  74.     return 0;     
  75. }