排序算法整理(3)快速排序

来源:互联网 发布:skype手机聊天软件 编辑:程序博客网 时间:2024/06/18 09:57

貌似需要整理一下排序算法了,正好最近在看的宋劲杉的《LINUX一站式编程》也提到了几个排序算法,于是决定把几个常见的排序算法都写写吧。

快速排序是我觉得排序算法中趣味排名top 1的排序。

快速排序每次只做一件事儿。在当前数组中,找到一个元素(叫做pivot),然后把比pivot小的放在pivot的左边,把比pivot打的放在pivot的右边。这样一趟下来,pivot被排好序了。也就是说,每趟就排序一个数。这个过程一般用函数partition(){}来表达。

然后,对pivot左边的数组重复刚才的那趟过程。

然后,对pivot右边的数组也重复刚才的那趟过程。

当最后发现每个数组都只有1个元素的时候,就OK了。

和归并排序一样,快速排序也使用了分治的思想, 所以时间复杂度都是Θ(n lg n)但是,快速排序比归并排序牛的地方在于,首先,快速排序的常数因子更小,也就是说,平均下来,虽然快速排序和归并排序是同一量级的时间复杂度,但是快速排序的需要时间比归并排序的需要时间少。第二,快速排序就地解决,无需额外空间,归并排序需要额外空间。

(theconstant factors hidden in the Θ(n lg n) notation are quite small  theadvantage of sorting in place 《CLRS算法导论》)

这里有个视频,展示快速排序的声音。

//下面两个函数用来依次打印数组。功能一样,参数不一样,这是为了方便不同的数据类型的调用要求。

void print_num_1(uint32_t* arr, uint32_t len){    for(int i=0;i<len;i++)        std::cout<<arr[i]<<"\t";    std::cout<<std::endl;    return;}void print_num_2(int* arr, int len){    for(int i=0;i<len;i++)        std::cout<<arr[i]<<"\t";    std::cout<<std::endl;    return;}
下面是快速排序的过程

//quick_sort_version_1int partition(int* arr, int st, int ed){    int j=st;    int i=j-1;    int pivot=arr[ed];    int temp;    while (j<=ed-1) {        if (pivot>arr[j]) {            i++;            temp=arr[i];            arr[i]=arr[j];            arr[j]=temp;        }        j++;    }    i++;    temp=arr[ed];    arr[ed]=arr[i];    arr[i]=temp;    //print_num_2(arr+st,ed-st+1);    return i;}void quick_sort_1(int* arr, int st, int ed){      if(st<ed) {        int pivot=partition(arr, st, ed);        quick_sort_1(arr,st, pivot-1);        quick_sort_1(arr,pivot+1,ed);    }}

后来,又看到了一个荷兰三色旗问题,于是扩展了一下快速排序的做法,详见这里。



原创粉丝点击