快速排序
原创、转载请注明出处。
快速排序优点:
速度快,不需要辅助空间。
分治:
划分问题:把数组的各个元素重排后分成左右2部分,使得左边任意元素都小于或等于右边任意元素。
递归求解:把左右2部分分别排序。
合并问题:不用合并,因为此时数组已经完全有序。
“划分过程”有多个版本,我第一次用的把第一个数作为基准,从前向后和从后向前分别找1个(找2个),交换。在处理细节时很麻烦,出了很多问题,后来用了找一个就交换的方法,个人感觉细节问题较少,代码如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
void mswap(int&a, int&b)
{
if (a != b)
{
a ^= b;
b ^= a;
a ^= b;
}
}
void qsort(int A[], int x, int y)
{
if (x >= y)
return;
int i = x, j = y;
while (i < j)
{
while (i < j&&A[i] < A[j])
{
j--;
}
mswap(A[i], A[j]);
while (i < j&&A[i] < A[j])
{
i++;
}
mswap(A[i], A[j]);
}
qsort(A, x, i - 1);
qsort(A, i + 1, y);
}
int main()
{
int n, a[10000];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
qsort(a, 0, n-1);
for (int i = 0; i < n; i++)
{
cout << a[i] << ' ';
}
return 0;
}
20
6 1 5 4 8 3 9 12 51 11 15 14 13 25 69 47 56 74 26 78
快速选择问题:
输出一个序列排序后第k大的数。借鉴快速排序的思想,序列分成2个左右2个序列后,可以根据第一序列的长度和k比较来确定是在左序列还是在右序列找。
快速排序的时间复杂度为:最坏情况O(n2),平均情况O(nlongn),但实践中几乎不可能达到最坏的情况,效率非常高。根据快速排序思想,可以在平均O(n)时间内选出数组中第k大的元素。

浙公网安备 33010602011771号