Chinaunix首页 | 论坛 | 博客
  • 博客访问: 139086
  • 博文数量: 94
  • 博客积分: 1572
  • 博客等级: 上尉
  • 技术积分: 925
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-04 00:03
文章分类

全部博文(94)

文章存档

2011年(94)

我的朋友

分类: C/C++

2011-04-07 14:31:25

上学时学过的快排算法,不过还真没去好好看更没有把它用语言实现。

现在正好想补补算法,自己写了一个实现。

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

我这个用的原地排序实现的,代码很短逻辑很简单而且我还添加了大量的注释。(如果发现代码或注释有问题告诉我啊)别被代码的这么长吓到,其实其中有 2/3 是注释。

  1. #include "stdio.h"
  2. /*
  3.  * 显示数组
  4.  * 只显示begin 到 end 下标间的数据到对应位置。
  5.  * 如,数组为 13, 17, 12 并先后执行:
  6.  * show(array, 3, 0, 2);
  7.  * show(array, 3, 1, 2);
  8.  * show(array, 3, 1, 1);
  9.  * 会显示为:
  10.  * 13 17 12
  11.  * 17 12
  12.  * 17
  13.  */
  14. void show(int array[], long maxlen, int begin, int end)
  15. {
  16.     int i = 0;

  17.     /* 不关心的数据用空格填充显示 */
  18.     for(i=0; i<begin; i++)
  19.         printf(" ");

  20.     for(i=begin; i<=end; i++)
  21.         printf("%4d", array);

  22.     printf("\n");
  23. }
  24. /*
  25.  * 两个数交换数值。
  26.  * 返回为 1 时说明进行了交换。
  27.  * 返回为 0 时说明两个数值相同没必要交换。
  28.  * 此返回值可以用于只想打印结果变化的情况。
  29.  */
  30. int swap(int *i, int *j)
  31. {
  32.    int temp;

  33.     if(*i == *j)
  34.         return 0;

  35.     temp = *i;
  36.     *i = *j;
  37.     *j = temp;

  38.     return 1;
  39. }

  40. /*
  41.  * 快速排序函数
  42.  * 此函数只会对begin下标(包括begin )和end(包括end)下标间的数据进行排序
  43.  */
  44. void quicksort(int array[], int maxlen, int begin, int end)
  45. {
  46.     int i, j;

  47.     if(begin < end) {
  48.         /* 因为开始值作为基准值不用移动,所以需要比较的值是从 begin+1 开始 */
  49.         i = begin + 1;
  50.         j = end;

  51.         /*
  52.          * 此循环的作用:array[begin] 为基准对 array[begin+1] 和 array[end]
  53.          * 之间的数进行初步分组,分组后的效果见循环后的描述
  54.          *
  55.          * 此处写 while(i != j) 是等价的,因为初始状态 i<=j 且每次i和j的
  56.          * 相对变化值为 1 所以不会出现 i>j的情况
  57.          */
  58.         while(i < j) {
  59.             /* 如果当前值大于 array[begin],把当前值换到 j 指向的位置,换位后 j 下标前移 */
  60.             if(array[i] > array[begin]) {
  61.                 if(swap(&array[i], &array[j]) == 1)
  62.                     show(array, maxlen, begin, end); /* 只显示begin 到 end 下标间的数据 */
  63.                 j--;
  64.             }
  65.             /* 否则 i 下标向后移动,准备比较下一个数。*/
  66.             else
  67.                 i++;
  68.         }
  69.         /*
  70.          * 在此时: i=j, array还没有进行判断处理
  71.          * 且 array[begin+1] ~ array[i-1] 都小于 array[begin]
  72.          * 且 array[i+1] ~ array[end] 都大于 array[begin]
  73.          *
  74.          * 接着: 对 array[begin] 和 array 比较并处理
  75.          * 目的是判断 array 应该分在左组还是右组,
  76.          * 同时还要把 array[begin] 的值放在分割线位置。
  77.          *
  78.          * 如果 array 的值大于 array[begin],则把 array[begin] 放在 i 前
  79.          * 也就是把 array[begin] 和 i 前的数换位
  80.          */
  81.         if (array > array[begin])
  82.             i--;

  83.         /* 把 array[begin] 放在 i 指向的位置 */
  84.         if(swap(&array[begin], &array) == 1)
  85.             /* 只显示begin 到 end 下标间的数据
  86.             show(array, maxlen, begin, end);

  87.         /* 再从分割线位置 i 分组分别排序 */
  88.         quicksort(array, maxlen, begin, i);
  89.         quicksort(array, maxlen, j, end);
  90.     }
  91. }
  92. int main(int argc, char* argv[])
  93. {
  94.     int array[10] = {49, 38, 65, 97, 48, 13, 27, 11, 56, 45};
  95.     int maxlen = sizeof(array) / sizeof(int);

  96.     show(array, maxlen, 0, maxlen-1); /* 打印初始顺序 */
  97.     quicksort(array, maxlen, 0, maxlen-1);
  98.     show(array, maxlen, 0, maxlen-1); /* 打印最终结果 */
  99.     getchar();

  100.     return 0;
  101. }
阅读(366) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~