快速排序算法

来源:互联网 发布:淘宝上hm折扣代购真假 编辑:程序博客网 时间:2024/05/18 16:54

快速排序算法最早由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以及ALGOL60编程语言的发明中都有卓越的贡献,是上世纪最伟大的计算机科学家之一。

时间复杂度:O(n*lgn)
最坏:O(n^2)
空间复杂度:O(n*lgn)
不稳定。

要注意很多细节问题,如:

  1. 我们知道,快速排序的分治partition过程有两种方法,一种方法是两个指针从首尾位分别向中间扫描的方法(大多数的人和一般的教材采用的是这第二种首尾向中间扫描法,算法导论的思考题7-1,P103页),这种方式是Hoare的最原始设计思想,俗称Hoare版本,需要注意的是partition操作里面一定要从右面开始,即,while(l<h && data[h]>=pivot)h--;
          XXXX;
          while(l<h && data[l]<=pivot)l++;
          XXXX; 的顺序结构。另外
    一种是上面所述的两个指针索引一前一后逐步向后扫描的方法(算法导论
    P95页上采用的是这种方法)
  2. partition过程中,要注意一些边界值问题。如i、j索引的初始化,for循环中,j从数组中第一个位置到倒数第二个位置h-1处,且是当data[j]<=privot(是小于等于,非小于),然后找到了之后,i++,再交换。最后还有一次data[i+1]与data[h]的交换。最后,便是返回值的问题,返回i+1。
  3. 第三个要注意的方面是递归处。if(l<h),才进入递归。

    主要要注意的问题就是上述三个方面。只要把握好细节,那么快速排序算法,二十几行自能搞定。

对于版本一可以引用 http://developer.51cto.com/art/201403/430986.htm 的图片,这样更容易理解。

版本一伪代码(Hoare版本)HOARE-PARTITION(A, p, r) 1  x ← A[p] 2  i ← p - 1 3  j ← r + 1 4  while TRUE 5      do repeat j ← j - 1 6           until A[j] ≤ x 7         repeat i ← i + 1 8           until A[i] ≥ x 9         if i < j10            then exchange A[i] ↔ A[j]11            else return j</strong></span>

版本二伪代码:QUICKSORT(A, p, r)1 if p < r2    then q ← PARTITION(A, p, r)   //关键3         QUICKSORT(A, p, q - 1)4         QUICKSORT(A, q + 1, r)数组划分快速排序算法的关键是PARTITION过程,它对A[p..r]进行就地重排:PARTITION(A, p, r)1  x ← A[r]2  i ← p - 13  for j ← p to r - 14       do if A[j] ≤ x5             then i ← i + 16                  exchange A[i] <-> A[j]7  exchange A[i + 1] <-> A[r]8  return i + 1</span></strong>


下面是实际的代码(可运行,我在code::blocks运行成功)

这几种方式在于分区操作的不同而已,其他都相同。

partition1:是原始的Hoare版本,即两个指针分别由首尾向中间进行扫描

partition1_1:是原始Hoare版本的另一版本,同理上面

partition2:是后来的改版,即两个指针索引从首部一前一后逐步向后扫描

可以将 quicksort函数中的分区操作由上面的这几种方式代替即可。


#include <iostream>#include <stdio.h>using namespace std;void swap(int* a,int* b){    int temp = *a;    *a = *b;    *b = temp;}int partition2(int data[],int l,int h){    int i=l-1,j;    int pivot = data[h];    for(j=l;j<h;j++){        if(data[j]<=pivot){            i++;            swap(&data[i],&data[j]);        }    }    swap(&data[h],&data[i+1]);    return i+1;}int partition1(int data[],int l,int h){    int pivot = data[l];    while(l<h){        while(l<h && data[h]>=pivot)h--;        data[l]=data[h];        while(l<h && data[l]<=pivot)l++;        data[h]=data[l];    }    data[l]=pivot;    return l;}int partition1_1(int data[],int l,int h){    int pivot = data[l];    while(l<h){        while(l<h && data[h]>=pivot)h--;        swap(&data[l],&data[h]);        while(l<h && data[l]<=pivot)l++;        swap(&data[l],&data[h]);    }    return l;}void quicksort(int data[],int l,int h){    if(l<h){        int pivot = partition2(data,l,h);        quicksort(data,l,pivot-1);        quicksort(data,pivot+1,h);    }}int main(){    int data[] = {87,45,12,32,56,89,98,1,34,65};    quicksort(data,0,9);    for(int t=0;t<10;t++){        cout<<data[t]<<" "<<endl;    }    return 0;}

如果未来我看不懂代码啦,请自己去看算法导论!一定能看懂

0 0