持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
快速排序:
快速排序是交换排序的一种,是由冒泡排序改进而得的。
大家回忆一下,在冒泡排序中,只是简单的对相邻的两个记录进行比较,这是冒泡排序的专属限定,但就是这种限定限制了冒泡排序的能力
它每次交换只能消除一个逆序
那么有没有一种算法,一次比较可以消除多个逆序呢?
of course!那就是——快速排序
算法思维:
1.在待排序的n个数中取第一个数(当然可以使任意一个数)作为枢轴
2.用temp来记录这个数
3.进过一趟排序后,把所有小于temp的数交换到前面,把所有大于temp的数交换到后面
4.把以temp为界的左右两边分成两个子表,再对着两个子表进行123这三步,直到每个子表长度为1,排序结束~
图片展示:
具体步骤:
1.选定数组的第一个数作为枢轴,用temp来记录它
2.设置两个指针——low和high,分别指向a[0]和a[n-1](数组末尾)
3.先从high的位置向左边开始搜索,找到第一个数值比temp小的数,此时high指向它,将这个数换到low所指向的位置,high停止移动
4.再从low开始向右边开始搜索,找到第一个数值比temp大的数,此时low指向它,将这个数换到high所指向的位置,low停止移动
5.接着进行34的循环,直到low和high重合,将temp的值赋值给low(或者high)
6.345就是一趟排序,对temp的左右两边进行拆分成两个子表,再次进行345,直到数组的每个子表的长度都是1,快速排序结束
核心代码:
找位置部分:
快速排序部分:
PS: 现在,我以下图为例子,进行快速排序的代码测试:
总代码:
#include<iostream>
using namespace std;
//找位置
int Partition(int a[], int low,int high) {
int temp = a[low];
while (low < high) {
while (low < high && a[high] >= temp)
high--;
a[low] = a[high];
while (low < high && a[low] < temp)
low++;
a[high] = a[low];
}
a[low] = temp;
return low;
}
//快速排序
void QuickSort(int a[], int low, int high) {
if (low < high) {//长度要大于一
//找枢轴
int mid = Partition(a, low, high);
//分别递归的搜索左右子表
QuickSort(a, low, mid - 1);
QuickSort(a, mid + 1, high);
}
}
//展示函数
void display(int a[], int n) {
for (int i = 0; i < n; i++)
cout << a[i] << " ";
}
int main()
{
int n;
cin >> n;
int* a = new int[n];
for (int i = 0; i < n; i++)
cin >> a[i];
QuickSort(a, 0, n - 1);
display(a, n);
cout << endl;
system("pause");
return 0;
}
测试结果:
PS: 代码无毒,请放心食用~
复杂度分析:
- 时间复杂度:
最好情况:O(nlog₂n)
最坏情况:O(n²)
平均情况:O(nlog₂n)
- 空间复杂度:
快速排序是递归的,执行时需要有一个栈来存放数据
空间复杂度:O(log₂n)
- 稳定性:
记录非顺次的移动导致排序方法是不稳定的
- 特点:
1.排序的过程由于需要定位,所以适用于顺序存储结构,不适用于链式存储结构
2.当n较大时,在平均情况下,快速排序是所有内部排序中速度最快的一种 PS: 这就是快速排序的全部内容了,点个赞再走吧~