Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2094604
  • 博文数量: 249
  • 博客积分: 1305
  • 博客等级: 军士长
  • 技术积分: 4733
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-17 10:37
个人简介

不懂的东西还有很多,随着不断的学习,不懂的东西更多,无法消灭更多不懂的东西,那就不断的充实自己吧。 欢迎关注微信公众号:菜鸟的机器学习

文章分类

全部博文(249)

文章存档

2015年(1)

2014年(4)

2013年(208)

2012年(35)

2011年(1)

分类: C/C++

2013-03-09 20:46:02

寻找最小的K个数

题目描述:查找最小的K个数

题目:输入n个整数,输出其中最小的K个数

例如,输入1、2、3、4、5、6、7、8这8个数字,则最小的4个数字为1、2、3、4。


第一节、各种思路,各种选择


  • 要求一个序列中最小的K个数,按照惯有的思维方式,很简单,先对这个序列从小到大排序,然后输出前面的最小的K个数即可;
  • 至于选取什么样的排序方法,第一时间应该想到的是快速排序,我们知道,快速排序平均时间复杂度为O(nlogn),然后再遍历序列中前K个元素输出,即可,总的时间复杂度为O(nlogn + k) = O(nlogn);——方法一
  • 再进一步想想,题目并没有要求要查找的k个数,甚至是后面的n-k个数是有序的,既然这样,咱们又何必对所有的n个数都进行排序呢?

    这个时候,想到了选择或交换排序,即遍历n个数,先把最先遍历到的K个数存入大小为k的数组之中,对这k个数,利用选择或交换排序,找到k个数中的最大数Kmax(Kmax为这K个元素的数组中最大的元素),用时间为O(k)(你应该知道,插入或选择排序查找操作需要O(k)的时间),后再继续遍历后n-k个数,x与Kmax比较:如果x< Kmax,则x代替Kmax,并再次重新找出K个元素的数组中的最大元素Kmax';如果x>Kmax,则不更新数组。这样每次更新和不更新数组所用的时间为O(k)或O(0),整趟下来,总的时间复杂度平均下来为:n*O(k) = O(n*k);——方法二


  • 当然,更好的办法是维护k个元素的最大堆,原理与上述第2个方案一致,即用容量为K的最大堆存储最先遍历的K个数,并假设它们即是最小的K个数,建堆需要O(k)后,有k1)。继续遍历数列,每次遍历一个元素x,与堆顶元素比较,x),否则不更新堆。这样下来,总费时O(k+(n-k)*logk) = O(nlogk)。此方法得益于在堆中,查找等各项操作时间复杂度均为logk(不然,就如上述思路2所述:直接用数组也可以找出前k个小的元素,用时O(n*k));——方法三
  • 按编程之美第141页上解法二的所述,类似快速排序的划分方法,N个数存储在数组S中,再从数组中随机选取一个数X(随机选取枢纽元,可做到线性期望时间O(N)的复杂度),把数组划分为Sa和Sb两部分,Sa<= X <=Sb,如果要查找的K个小的元素小于Sa中的元素个数,则返回Sa中较小的K个元素,否则返回Sa中K个小的元素 + Sb中小的K-|Sa|个元素。像上述过程一样,这个运用类似快速排序的partition的快速选择Select算法寻找最小的K个元素,在最坏的情况下亦能做到O(N)的复杂度。不过值得一提的是,这个快速选择Select算法是选择数组中“中位数的中位数”作为枢纽元,而非随机选择枢纽元;——方法五
  • Randomized-Select,每次都是随机选择数列中的一个元素作为主元,在O(n)的时间内找到第K小的元素,然后遍历输出前面的K个小的元素。如果能的话,那么总的时间复杂度为线性期望时间:O(n+k) = O(n)(当n比较小时);——方法六
  • 线性时间的排序,即计数排序,时间复杂度虽能达到O(n),但是,限制条件太多了,不常用;——方法七
  • 可以用最小堆初始化数组,然后取这个优先队列前k个值。复杂度为O(n)+k*O(logn)“。意思是针对整个数组序列建立最小堆,建堆所用时间为O(n),然后取堆中的前k个数,即总的时间复杂度为:O(n+k*logn)。——方法八
  • 与上述思路7类似,不同的是在对元素数组原地建立最小堆O(n)后,然后提取K次,但是每次提取时,换到顶部的元素只需要下移顶多K次就足够了,下移次数逐次减少(而上述思路7每次提取都需要logn,所有提取K次,思路7需要K*logn,而本思路8只需要K^2);——方法九(没想明白)

    
    上面的这些思路来自:http://blog.csdn.net/v_JULY_v 
   非常感谢作者,提高了这么多思路。


第二节、C语言实现
    下面的C语言代码,实现了上述的大部分思路,除了快速select算法(主元选择中位数的中位数)和计数排序以及方法九外,没有实现,其他的都已经实现。《已经经过更改了,第一次写的时候,发现代码的实现复杂度并没有达到目的,回过头又看了一遍,发现了这个问题。》

点击(此处)折叠或打开

  1. /*
  2.  *        Author: 梦醒潇湘love
  3.  *        Date :2013/3/9
  4.  *        Email :9974**77140@qq.com
  5.  *
  6.  *        More Infomation:
  7.  *        1> 相关函数之间只有一个空行
  8.  *        2> 不相关函数之间有三个空行,即代表新的方法实现的开始
  9.  *        3> 下面函数的实现,依次是按照上文论述的方法实现的
  10.  *        4> 感谢July提高这么多的思路,非常感谢
  11.  *        5> 代码为梦醒潇湘love实现,若有错误,请指教
  12.  *
  13.  *        求最小的K个数
  14.  */

  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <errno.h>

  19. #define MAXNUM 1000000        //产生的随机数的个数最大值
  20. #define K 10                //寻找前K个最小的数
  21. #define NUM    20                //从data.txt中读取NUM个数组

  22. //#define DEBUG
  23. //#define DEBUG_RANDOM        //第一次运行时取消注释,再次运行时,为了避免data.txt文件过大,建议注释掉该行
  24. #define DEBUG_QUICKSORT        //快速排序--随机主元、固定主元
  25. #define DEBUG_EXCHANGE //类交换排序
  26. #define DEBUG_MAXHEAP //最大堆
  27. #define DEBUG_QUICKSELECT //快速选择
  28. #define DEBUG_MINHEAP //最小堆

  29. /* 函数功能: 产生随机数,然后写到data.txt文件中
  30.  * 返回值 :
  31.  * 参数 :
  32.  */
  33. void Random_Num()
  34. {
  35.     long num = 0;
  36.     long i = 1;
  37.     FILE *fp;
  38.     
  39.     fp = fopen("./data.txt", "a");
  40.     if(fp == NULL)
  41.     {
  42.         fprintf(stderr, "fopen() error: %s\n", strerror(errno));
  43.         return ;
  44.     }
  45.     
  46.     printf("请输入需要产生的随机数的个数(<= 1000000):\n");
  47.     scanf("%ld", &num);
  48.     if(num > MAXNUM)
  49.     {
  50.         fprintf(stderr, "所输入的产生的随机数个数值过大.\n");
  51.         return;
  52.     }
  53.     
  54.     srand((unsigned)time(NULL));
  55.     
  56.     for(i = 1; i <= num; i++)
  57.     {
  58.         long temp = rand() % 1000000;
  59.         fprintf(fp, "%ld ", temp);
  60.     }
  61.     
  62.     fclose(fp);
  63. }

  64. /*
  65.  * 函数功能:打印前K个最小的元素
  66.  * 返回值 : void
  67.  * 参数 :
  68.  * @prama a[] 数组a
  69.  * @prama k 前几个最小的元素
  70.  */
  71. void Print(long a[], int k)
  72. {
  73.     int i = 1;
  74.     for(i = 1; i <= k; i++)
  75.     {
  76.         printf("%ld ", a[i]);
  77.     }
  78.     printf("\n");
  79. }



  80. /*
  81.  * 函数功能: 交换两个数
  82.  * 返回值 :void
  83.  * 参数     :
  84.  *    @prama *a 数a
  85.  *    @prama *b 数b
  86.  */
  87. void Swap(long *a, long *b)
  88. {
  89.     long temp = *a;
  90.     *a = *b;
  91.     *b = temp;
  92. }

  93. /*
  94.  * 函数功能: 快速排序中的分治方法-----随机主元
  95.  * 返回值 : 返回的界限
  96.  * 参数 :
  97.  * @prama a[] 数组a
  98.  * @prama first 数组上标
  99.  * @prama last 数组下标
  100. */
  101. int Partition_Rand(long a[], int first, int last)
  102. {
  103.     int priot = first + rand() % ( last - first + 1);
  104.     Swap(&a[first], &a[last]);
  105.     
  106.     long key = a[first];
  107.     
  108.     while(first < last)
  109.     {
  110.         while(first < last && a[last] >= key)
  111.         {
  112.             last--;
  113.         }
  114.         Swap(&a[first], &a[last]);

  115.         while(first < last && a[first] <= key)
  116.         {
  117.             first++;
  118.         }
  119.         Swap(&a[first], &a[last]);
  120.     }
  121.     
  122.     return first;
  123. }


  124. /*
  125.  * 函数功能: 快速排序中分治方法-----固定主元
  126.  * 返回值 : 返回的界限
  127.  * 参数 :
  128.  * @prama a[] 数组a
  129.  * @prama first 数组上标
  130.  * @prama last 数组下标
  131. */
  132. int Partition(long a[], int first, int last)
  133. {
  134.     long key = a[first];
  135.     
  136.     while(first < last)
  137.     {
  138.         while(first < last && a[last] >= key)
  139.         {
  140.             last--;
  141.         }
  142.         Swap(&a[first], &a[last]);

  143.         while(first < last && a[first] <= key)
  144.         {
  145.             first++;
  146.         }
  147.         Swap(&a[first], &a[last]);
  148.     }
  149.     
  150.     return first;
  151. }

  152. /*
  153.  * 函数功能:快速排序算法----随机主元
  154.  * 返回值 : void
  155.  * 参数 :
  156.  * @prama a[] 数组a
  157.  * @prama first 数组上标
  158.  * @prama last 数组下标
  159.  */
  160. void Quick_Rand_Sort(long a[], int first, int last)
  161. {
  162.     if(first < last)
  163.     {
  164.         int priot = Partition_Rand(a, first, last);
  165.         Quick_Rand_Sort(a, first, priot - 1);
  166.         Quick_Rand_Sort(a, priot + 1, last);
  167.     }
  168. }

  169. /*
  170.  * 函数功能:快速排序算法----固定主元
  171.  * 返回值 : void
  172.  * 参数 :
  173.  * @prama a[] 数组a
  174.  * @prama first 数组上标
  175.  * @prama last 数组下标
  176.  */
  177. void Quick_Sort(long a[], int first, int last)
  178. {
  179.     if(first < last)
  180.     {
  181.         int priot = Partition(a, first, last);
  182.         Quick_Sort(a, first, priot - 1);
  183.         Quick_Sort(a, priot + 1, last);
  184.     }
  185. }



  186. /*
  187.  * 函数功能:找到数组a中的最大值,返回最大值所在的下标
  188.  * 返回值 :返回最大值元素的下标
  189.  * 参数 :
  190.  * @prama a[] 数组a
  191.  * @prama length 数组长度
  192.  */
  193. int Find_Max(long a[], int length)
  194. {
  195.     int i = 1;
  196.     int max = 1;

  197.     for(i = 1; i <= length; i++)
  198.     {
  199.         if(a[max] < a[i])
  200.         {
  201.             max = i;
  202.         }
  203.     }
  204.     
  205.     return max;
  206. }

  207. /*
  208.  * 函数功能: 类似于交换排序的方法求取最小K个数
  209.  * 返回值 :void
  210.  * 参数 :
  211.  * @prama a[] 数组a
  212.  * @prama k 所求取的最小数的个数
  213.  *
  214.  * 说明:
  215.  *     求取最小的K个数,并没有要求排序,所以,这里每次求取k个元素数组中的最大值的下标*/
  216. void Exchange_Sort(long a[], int k)
  217. {
  218.     int i = 1;

  219.     //先从data.txt中读取K个元素放到数组a中
  220.     FILE *fp;
  221.     fp = fopen("./data.txt", "r");
  222.     if(fp == NULL)
  223.     {
  224.         fprintf(stderr, "fopen() error: %s\n", strerror(errno));
  225.         return;
  226.     }

  227.     while((i <= k) && (fscanf(fp, "%ld", &a[i]) != EOF))
  228.     {
  229.         i++;
  230.     }

  231.     int max = Find_Max(a, k);
  232.     long temp = 0;    

  233.     int j = k + 1; // for test
  234.     //while((fscanf(fp, "%ld", &temp) != EOF) && (j <= NUM))    //为了测试,求前20个数字的
  235.     while((fscanf(fp, "%ld", &temp) != EOF))                //求整个文件中数字的最小K个数
  236.     {
  237.         j++;
  238.         if(a[max] <= temp)
  239.         {
  240.             //如果当前数组a中的最大值小于读取的数,则继续
  241.             continue;
  242.         }
  243.         else
  244.         {
  245.             //如果当前数组a中的最大值大于读取的数,则需要交换,重新获得最大值下标
  246.             a[max] = temp;
  247.             max = Find_Max(a, k);
  248.         }
  249.     }
  250.     
  251.     fclose(fp);
  252. }



  253. /*
  254.  * 函数功能:调整最大堆,以保持最大堆的性质
  255.  * 返回值 :void
  256.  * 参数 :
  257.  * @prama a[] 数组a
  258.  * @prama i 需要调整的节点在数组中的位置
  259.  * @prama len 当前需要调整的长度
  260.  */
  261. void Modify_Heap(long a[], int i, int length)
  262. {
  263.     int left = 2 * i;
  264.     int right = 2 * i + 1;
  265.     int largest = i;

  266.     if(left <= length && a[left] >= a[i])
  267.     {
  268.         largest = left;
  269.     }
  270.     else
  271.     {
  272.         largest = i;
  273.     }
  274.     if(right <= length && a[right] >= a[largest])
  275.     {
  276.         largest = right;
  277.     }
  278.     
  279.     if(largest != i)
  280.     {
  281.         Swap(&a[i], &a[largest]);
  282.         Modify_Heap(a, largest, length);
  283.     }
  284. }

  285. /*
  286.  * 函数功能: 建立最大堆
  287.  * 返回值 :void
  288.  * 参数 :
  289.  * @prama a[] 数组a
  290.  * @prama len 数组a的长度
  291.  */
  292. void Build_Max_Heap(long a[], int length)
  293. {
  294.     int i;
  295.     for(i = length / 2; i>= 1; i--)
  296.     {
  297.         Modify_Heap(a, i, length);
  298.     }
  299. }

  300. /*
  301.  * 函数功能:利用最大堆求最小k个数
  302.  * 返回值 :void
  303.  * 参数 :
  304.  * @prama a[] 数组a
  305.  * @prama k 数组a的长度,也是所求的最小数的个数
  306.  */
  307. void Max_Heap_Sort(long a[], int k)
  308. {
  309.     
  310.     FILE *fp;
  311.     
  312.     fp = fopen("./data.txt", "r");
  313.     if(fp == NULL)
  314.     {
  315.         fprintf(stderr,"fopen() error: %s\n", strerror(errno));
  316.         return;
  317.     }

  318.     //先读取k个元素
  319.     int i = 1;
  320.     while((i <= k) && (fscanf(fp, "%ld", &a[i]) != EOF))
  321.     {
  322.         i++;
  323.     }

  324.     //建立最大堆
  325.     Build_Max_Heap(a, k);

  326.     //寻找最小的k个数哦
  327.     long temp = 0;
  328.     int j = k + 1; // for test
  329.     //while((j <= NUM) && (fscanf(fp, "%ld", &temp) != EOF)) //方便测试,文件中的前20个数据    
  330.     while((fscanf(fp, "%ld", &temp) != EOF))    // 整个文件的
  331.     {
  332.         j++;
  333.         if(temp < a[1])
  334.         {
  335.             a[1] = temp;
  336.             Modify_Heap(a, 1, k);
  337.         }
  338.     }

  339.     fclose(fp);
  340. }
  341.     


  342. /*
  343.  * 函数功能:快速选择第k小元素
  344.  * 返回值 :第k小元素
  345.  * 参数 :
  346.  * @prama a[] 数组a
  347.  * @prama first 数组上标
  348.  * @prama last 数组下标
  349.  * @prama i 第i小元素
  350.  *
  351.  * 时间复杂度:
  352.  *     平均时间复杂度:O(n)
  353.  *     最坏时间复杂度:O(n^2)
  354.  */
  355. long Quick_Select(long a[], int first, int last, int i)
  356. {
  357.     if(first == last)
  358.     {
  359.         //return a[first];
  360.         return first;
  361.     }
  362.     
  363.     long p = Partition_Rand(a, first, last); //这里应该选用随机主元分治方法
  364.     long k = p - first + 1;
  365.     if(i == k)
  366.     {
  367.         //return a[p];
  368.         return k;
  369.     }
  370.     if(i < k)
  371.     {
  372.         return Quick_Select(a, first, p - 1, i);
  373.     }
  374.     else
  375.     {
  376.         return Quick_Select(a, p + 1, last, i - k);
  377.     }
  378. }



  379. /*
  380.  * 函数功能: 调整最小堆,使其满足最小堆的性质
  381.  * 返回值 : void
  382.  * 参数 :
  383.  *     @prama a[] 数组a
  384.  *     @prama i 调整第i个节点
  385.  *     @prama length数组a的长度
  386.  *
  387.  * 时间复杂度为:O(logn)
  388.  */    
  389. void Modify_Min_Heap(long a[], long i ,long length)
  390. {
  391.     long left = 2 * i;
  392.     long right = 2 * i + 1;
  393.     long least = i;
  394.     
  395.     if(left <= length && a[left] <= a[i])
  396.     {
  397.         least = left;
  398.     }
  399.     else
  400.     {
  401.         least = i;
  402.     }
  403.     if(right <= length && a[right] <= a[least])
  404.     {
  405.         least = right;
  406.     }
  407.     if(least != i)
  408.     {
  409.         Swap(&a[i], &a[least]);
  410.         Modify_Min_Heap(a, least, length);
  411.     }
  412. }

  413. /*
  414.  * 函数功能:建立最小堆
  415.  * 返回值 :void
  416.  * 参数 :
  417.  * */
  418. void Build_Min_Heap(long a[], long length)
  419. {
  420.     int i = 1;
  421.     for(i = length/2; i>= 1; i--)
  422.     {
  423.         Modify_Min_Heap(a, i, length);
  424.     }
  425. }

  426. /*
  427.  * 函数功能:最小堆排序
  428.  * 返回值 : void
  429.  * 参数 :
  430.  * @prama a[] 数组a
  431.  * @prama len 数组a长度
  432.  */
  433. void Min_Heap_Sort(long a[], long length)
  434. {
  435.     int i = 0;
  436.     
  437.     Build_Min_Heap(a, length);

  438. #ifdef DEBUG
  439.     for(i = 1; i <= length; i++)
  440.         printf("%ld ", a[i]);

  441.     printf("\n");
  442. #endif

  443.     for(i = length; i >= 1; i--)
  444.     {
  445.         Swap(&a[1], &a[i]);
  446.         Modify_Min_Heap(a, 1, i - 1);
  447.     }
  448. #ifdef DEBUG
  449.     for(i = 1; i <= length; i++)
  450.         printf("%ld ", a[i]);

  451.     printf("\n");
  452. #endif
  453. }

  454. /*
  455.  * 函数功能:通过建立的最小堆,求得最小的K个数
  456.  * 返回值 :void
  457.  * 参数 :
  458.  * @param a[] 数组a
  459.  * @param length 数组的长度
  460.  * 时间复杂度:
  461.  * O(n) + k*logn
  462.  */
  463. void Min_Heap_Find(long a[], long length)
  464. {
  465.     int i = 1;
  466.     
  467.     //建立最小堆
  468.     Build_Min_Heap(a, length);

  469.     int min = a[1];

  470.     printf("%d ", min);
  471.     
  472.     //for(i = 2; i <= K && length > 0; i++, length--)
  473.     for(i = 2; i <= K; i++)
  474.     
  475.     {
  476.         a[1] = a[length];
  477.         Modify_Min_Heap(a, 1, length);
  478.         printf("%d ", a[1]);
  479.     }
  480. }


  481. int main(int argc, char **argv)
  482. {
  483.     int first = 1;
  484.     int last = NUM;

  485. #ifdef DEBUG_RANDOM
  486.     //产生随机数,然后将产生的随机数写入到data.txt文件中
  487.     Random_Num();
  488. #endif
  489.     
  490.     //从data.txt中读取20个数据
  491.     long a[NUM + 1] = {0};
  492.     int i = 1;    
  493.     FILE *fp = NULL;

  494.     fp = fopen("./data.txt", "r");
  495.     if(fp == NULL)
  496.     {
  497.         fprintf(stderr, "fopen() error: %s", strerror(errno));
  498.         return -1;
  499.     }

  500.     while((fscanf(fp, "%ld", &a[i]) != EOF) && (i <= NUM))
  501.     {
  502.         i++;
  503.     }
  504.     printf("从data.txt中读取的NUM个数为:\n", NUM);
  505.     for(i = 1; i <= NUM; i++)
  506.     {
  507.         if( i % 11 == 0)
  508.         {
  509.             printf("\n");
  510.         }
  511.         printf("%ld ", a[i]);
  512.     }
  513.     printf("\n\n");
  514.     
  515.     fclose(fp);
  516.         
  517. #ifdef DEBUG_QUICKSORT
  518.     //用快速排序方式获得最小的K个元素(为了方便测试,从data.txt前20个元素中选最小K个)
  519.     long b[ NUM + 1];
  520.     long bc[NUM + 1];
  521.     first = 1;
  522.     last = NUM;

  523.     memcpy(b, a, sizeof(a));

  524.     Quick_Rand_Sort(b, first, last);
  525.     
  526.     printf("通过快速排序---随机主元找到最小的%d个数为:\n", K);    
  527.     Print(b, K);
  528.     
  529.     memcpy(bc, a, sizeof(a));
  530.     Quick_Sort(bc, first, last);    
  531.     printf("\n通过快速排序---固定主元找到最小的%d个数为:\n", K);    
  532.     Print(bc, K);            
  533. #endif
  534.         
  535. #ifdef DEBUG_EXCHANGE
  536.     //用类似于交换排序的方式获得最小的K个元素    
  537.     //这里所求的没有进行排序,只是每次找到k个元素中的最大值
  538.     long c[NUM + 1] = {0};
  539.     
  540.     Exchange_Sort(c, K);
  541.     
  542.     printf("\n通过类似交换排序的方法找到最小的%d个数为:\n", K);
  543.     Print(c, K);
  544. #endif    

  545. #ifdef DEBUG_MAXHEAP
  546.     //用最大堆方式获得最小的K个元素(为了方便测试,从data.txt前20个元素中选最小的)
  547.     long d[NUM + 1] = {0};
  548.     
  549.     Max_Heap_Sort(d, K);
  550.     
  551.     printf("\n通过最大堆排序的方法找到最小的%d个数为:\n", K);
  552.     Print(d, K);
  553. #endif

  554. #ifdef DEBUG_QUICKSELECT
  555.     //用快速选择方法获得最小K个数
  556.     long f[NUM + 1] = {0};
  557.     
  558.     memcpy(f, a, sizeof(a));

  559.     printf("\n通过快速选择的方法找到最小的%d个数为:\n", K);
  560.     
  561.     //这个有序
  562.     //for(i = 1; i <= K; i++)    //Quick_Sort的返回值不一样
  563.     //{
  564.     //    printf("%ld ", Quick_Select(f, first, last, i));
  565.     //}
  566.     
  567.     //这个无序
  568.     long num = Quick_Select(f, first, last, K);
  569.     for(i = 1; i <= K; i++)
  570.     {
  571.         printf("%ld ", f[i]);
  572.     }
  573.     printf("\n");

  574.     
  575. #endif

  576. #ifdef DEBUG_MINHEAP
  577.     //最小堆
  578.     long g[NUM + 1];
  579.     
  580.     memcpy(g, a, sizeof(a));
  581.     
  582.     printf("\n通过最小堆的方法找到最小的%d个数为:\n", K);
  583.     Min_Heap_Find(a, NUM);
  584.     /*
  585.     Min_Heap_Sort(g, (long)NUM);
  586.     long tmp = 1;
  587.     long j = 1;
  588.     for(j = NUM; j >= 1; j--)
  589.     {
  590.         printf("%ld ", g[j]);
  591.         if(tmp == K)
  592.         {
  593.             break;
  594.         }
  595.         tmp++;
  596.     }
  597.     */
  598.     printf("\n");
  599. #endif

  600.     return 0;
  601. }
    代码如下所示。  测试结构如下所示。

    

    不知道怎么传文件,上述代码可能太长,如果看起来麻烦请谅解
    另外种没有实现的(计数排序除外,这个比较简单),等搞明白后再添加。
    上面代码是自己实现的,肯定有错误或者代码不规范之处,敬请纠正和指教。
    谢谢。

   

   哈,终于把这个算是弄得相对清楚了,关于各种实现方式的时间复杂度分析,再好好的看看。
    一个愉快的晚上,有所收获。

    感谢今天。





                                                                                                        梦醒潇湘love
                                                                                                      2013-03-09  20:41




  









阅读(8869) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~