快速排序
快速排序是排序算法中比较经典的一种排序算法。这里给一个 c++ 的简单实现。这里的模板用的并不好,需要改进。
quicksort 调用过程比较简单,就只是一个递归。每次调用 partation 都会将一个数字放到最终合适的位置上。这里选的是子序列末尾的数。当然可以先随机选一个数然后和最后一个数进行交换以达到随机化的目的。quicksort 整个算法的平均时间复杂度为 O(n*logn),详细分析请看 算法导论 第七章内容。
template <typename T> int quicksort(T *arr, int from, int to, int (*cmp)(T,T)) { if(to <= from) return 1; int bar = partation(arr, from, to, cmp); quicksort(arr, from, bar-1, cmp); quicksort(arr, bar+1, to, cmp); }
快排的关键是 partation 函数,这个函数用于返回一个位置,在此位置之前的数都不大于这个数字,在此位置之后的数都大于这个数。
template <typename T> int partation(T *arr, T from, T to, int (*cmp)(T, T)) { T pivot = *(arr + to); T lastSmall = from - 1; for(int i = from; i < to; i++) { //must be <= if(cmp(*(arr+i), pivot)) { lastSmall++; swap(arr+lastSmall, arr+i); } } lastSmall++; swap(arr+lastSmall, arr+to); return lastSmall; }
交换函数和比较函数如下:
template<typename T> int lt(T a, T b) { return a <= b; } template <typename T> int swap(T *a, T *b) { if(*a == *b) return 1; *a ^= *b; *b ^= *a; *a ^= *b; return 1; }
注意交换函数 swap 使用的是异或版本,一定要确定两数不相等。
算法导论中第一部分第七章专门讲快排,说明快排的重要性。事实上c语言 stdlib.h 头文件中包含了一个 qsort 快速排序函数,这个函数有四个参数,分别是:1个数组指针,1 个数组起始位置, 1 个数组结束为止, 1 个比较函数指针。平常请直接使用这个 qsort 函数,自行实现的版本要经过严格测试才行,像上面的这个函数版本,要再进一步的改进才行,这里只是为了理解快排的思想而实现的,慎用于生产中。