Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279730
  • 博文数量: 88
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 840
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-20 21:13
文章分类

全部博文(88)

文章存档

2022年(1)

2017年(1)

2016年(2)

2015年(1)

2014年(83)

分类: C/C++

2014-05-01 18:10:49

以前自己写过快速排序,但是代码看起来比较臃肿,计算分离点的时候用了2重循环来回判断,时间复杂度比较高。今天在看《算法导论》的时候,书上的方法非常经典,巧妙利用一个标志变量就实现了只用一重循环来partition。

           快排的基本原理是:定义一个基准点base,然后通过遍历整个序列,把小于base的放在左边,大于base的放在右边,然后对划分后的两段序列进行递归调用,递归的条件是start=end时,递归结束,然后工作栈不断返回,结束排序。通过一个标志变量i来优化的,虽然时间复杂度减少不多,但是当序列特别长的时候,能够更加节省时间。

           以下是算法代码和测试代码:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <conio.h>

  3. //函数原型
  4. void swap(int *a,int *b);
  5. int partition(int A[],int start,int end);
  6. void quick_sort(int A[],int start,int end);
  7. //测试代码
  8. int main()
  9. {
  10.     int test[11]={-1,2,5,6,7,8,9,1,4,3,10};
  11.     quick_sort(test,1,9);
  12.     for(int i=1;i<11;i++)
  13.         printf("%d ",test[i]);
  14.     getch();
  15. }

  16. //划分区域
  17. int partition(int A[],int start,int end)
  18. {
  19.     int base=A[end];//以最后一个数作为划分的基点
  20.     int i=start-1; //i表示比base小且最靠右的数的下标,这里很巧妙的利用i来消除了另外一次循环。
  21.     for(int j=start;j<end;j++)
  22.     {
  23.         if(A[j]<=base)
  24.         {
  25.             i++;
  26.             swap(&A[i],&A[j]);
  27.         }
  28.     }
  29.     swap(&A[i+1],&A[end]);
  30.     return i+1;
  31. }


  32. void quick_sort(int A[],int start,int end)
  33. {
  34.     //注意这里不要忘记递归结束的条件
  35.     if(start<end)
  36.     {
  37.         int t=partition(A,start,end);
  38.         quick_sort(A,start,t-1);
  39.         quick_sort(A,t+1,end);
  40.     }
  41. }

  42. //交换
  43. void swap(int *a,int *b)
  44. {
  45.     int temp=*a;
  46.     *a=*b;
  47.     *b=temp;
  48. }

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