快速排序
Posted anthony-ling
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序相关的知识,希望对你有一定的参考价值。
快速排序
最坏情形时间复杂度\(\mathrm{O}(N^2)\)
平均运行时间\(\mathrm{O}(NlogN)\)
//快速排序驱动程序
void QuickSort(int *a; int N)
{
Qsort(a, 0, N - 1);
}
//实现三数中值分割法的程序
int Median3(int *a, int Left, int Right)
{
int Center = (Left + Right) / 2;
if (a[Left] < a[Center]) swap(&a[Left], &a[Center]);
if (a[Left] < a[Right]) swap(&a[Left], &a[Right]);
if (a[Center] < a[Right]) swap(&a[Center], &a[Right]);
swap(&a[Center], &a[Right - 1]);
return a[Right - 1];
}
//快速排序主例程
#define Cutoff 3
void Qsort(int *a, int Left, int Right)
{
int i, j;
int Pivot;
if (Left + Cutoff <= Right)
{
Pivot = Median3(a, Left, Right);
i = Left;
j = Right - 1;
for (; ; )
{
while (a[++i] < Pivot) {}
while (a[--j] > Pivot) {}
if (i < j) swap(&a[i], &a[j]);
else break;
}
swap(&a[i], &a[Right - 1]);
Qsort(a, Left, i - 1);
Qsort(a, i + 1, Right);
}
else InsertionSort(a + Left, Right - Left + 1);//做一次插入排序
}
1 该算法通过选取一个枢纽元,然后使数组的剩余部分大于枢纽元的在一侧,小于枢纽元的在另一侧,然后对两边使用同样的方法,就是这样使用递归的操作是的整个数组有序
2 算法的移动策略大致如图:
- 假如初始数组为8,1,4,9,6,3,5,2,7,0然后选取6为枢纽元,然后将枢纽元与数组最后一个元素交换
8 | 1 | 4 | 9 | 0 | 3 | 5 | 2 | 7 | 6 |
---|
- 然后使用两个指针
i
,j
,i
从第一个元素开始,j
从倒数第二个元素开始
8 | 1 | 4 | 9 | 0 | 3 | 5 | 2 | 7 | 6 |
---|---|---|---|---|---|---|---|---|---|
i↑ | - | - | - | - | - | - | - | j↑ | - |
- 将
i
向右移动,将j
向左移动,当i
指向的数字大于枢纽元时停下,当j
指向的数字小于枢纽元时停下
8 | 1 | 4 | 9 | 0 | 3 | 5 | 2 | 7 | 6 |
---|---|---|---|---|---|---|---|---|---|
i↑ | - | - | - | - | - | - | j↑ | - | - |
- 此时若
i
在j
的左边,则交换两个元素
2 | 1 | 4 | 9 | 0 | 3 | 5 | 8 | 7 | 6 |
---|---|---|---|---|---|---|---|---|---|
i↑ | - | - | - | - | - | - | j↑ | - | - |
- 经过若干次这样的操作后
i
指针将跑到j
指针的右边
2 | 1 | 4 | 5 | 0 | 3 | 9 | 8 | 7 | 6 |
---|---|---|---|---|---|---|---|---|---|
- | - | - | - | - | j↑ | i↑ | - | - | - |
- 此时
i
和j
已交错,故不再交换,此时将枢纽元与i
指向的元素交换,至此就完成了一次快速排序
2 | 1 | 4 | 5 | 0 | 3 | 6 | 8 | 7 | 9 |
---|---|---|---|---|---|---|---|---|---|
- | - | - | - | - | j↑ | i↑ | - | - | - |
以上是关于快速排序的主要内容,如果未能解决你的问题,请参考以下文章