2014.06.17 05:15
简介:
快速排序是实际应用最广的基于内存的不稳定的比较排序。拥有O(n * log(n))的平均复杂度和O(n^2)的最坏复杂度。采用的思路是分治法,递归实现。
描述:
快速排序的基本思路,是从数组中选取一个值pivot作为参照,使得比pivot小的都在它左边,比pivot大的都在它右边。pivot的英文意思是支点,从这个你应该能猜到——左右的元素最好数目接近。如果偏向很多,效果就不好了。如此递归排序两个小段,就可以完成整个数组的排序了。思路很简单,实现起来却不是那么简单。讲解快速排序的原理也许得废很多话,不如逐行仔细阅读代码,体会每一步执行的过程。我认为这其中最难理解的,莫过于++和--之处。由于实现快速排序的难度,光是“写个快排看看”就算是一道面试题了。
由于我曾经在面试时被直接要求写出快速排序,当时的我完全无力招架(那时可以说基本不会写代码,而且还自我感觉良好)。所以现在一提到快速排序我就非常小心,几乎是按照教材上的代码实现的。在这段不算长的代码中随便改掉一点,都容易造成各种错误。实际上我在别人的不少技术博客中的确找到了错误,有些运行结果明显不对,但代码长得和正确版本几乎一模一样。这应该就是那种很不直观,但代码简洁的神级之算法吧。
实现:
1 // My implementation for quick sort. 2 #include <iostream> 3 #include <vector> 4 using namespace std; 5 6 const int CUT_OFF = 4; 7 8 static void swap(int &x, int &y) 9 { 10 int tmp; 11 12 tmp = x; 13 x = y; 14 y = tmp; 15 } 16 17 static int medianThree(vector<int> &v, int left, int right) 18 { 19 int center = (left + right) / 2; 20 21 if (v[left] > v[right]) { 22 swap(v[left], v[right]); 23 } 24 if (v[left] > v[center]) { 25 swap(v[left], v[center]); 26 } 27 if (v[center] > v[right]) { 28 swap(v[center], v[right]); 29 } 30 swap(v[center], v[right - 1]); 31 32 return v[right - 1]; 33 } 34 35 static void quickSortRecursive(vector<int> &v, int left, int right) 36 { 37 if (right - left + 1 >= CUT_OFF) { 38 int i, j; 39 int pivot = medianThree(v, left, right); 40 41 i = left; 42 j = right - 1; 43 while (true) { 44 while (v[++i] < pivot) {} 45 while (v[--j] > pivot) {} 46 if (i < j) { 47 swap(v[i], v[j]); 48 } else { 49 break; 50 } 51 } 52 swap(v[i], v[right - 1]); 53 quickSortRecursive(v, left, i - 1); 54 quickSortRecursive(v, i + 1, right); 55 } else { 56 int i, j; 57 int tmp; 58 59 for (i = left + 1; i <= right; ++i) { 60 tmp = v[i]; 61 for (j = i; j > left && v[j - 1] > tmp; --j) { 62 v[j] = v[j - 1]; 63 } 64 v[j] = tmp; 65 } 66 } 67 } 68 69 void quickSort(vector<int> &v) 70 { 71 int n = (int)v.size(); 72 quickSortRecursive(v, 0, n - 1); 73 } 74 75 int main() 76 { 77 vector<int> v; 78 int n, i; 79 80 while (cin >> n && n > 0) { 81 v.resize(n); 82 for (i = 0; i < n; ++i) { 83 cin >> v[i]; 84 } 85 quickSort(v); 86 for (i = 0; i < n; ++i) { 87 cout << v[i] << ' '; 88 } 89 cout << endl; 90 } 91 92 return 0; 93 }