随笔- 509  文章- 0  评论- 151  阅读- 22万 

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 }
复制代码

 

 posted on   zhuli19901106  阅读(646)  评论(2编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示