基础数据结构之八大排序算法(八)快速排序
⑧快速排序(特点:数据越无序速度越快,时间复杂度越小)
(递归:函数中自己调用自己)
时间复杂度:O(nlogn) 时间复杂度最好是O(nlogn),最坏是 O(n^2)->当数据完全有序时调用快速排序,平均时间复杂度为O(nlogn)
空间复杂度:O(nlogn) 问题规模与其额外辅助变量有关
稳定性:不稳定 存在跳跃交换
(以顺序表作为待排序对象)
1.基本思想:
我们将数据的第一个值作为我们的基准值,然后以基准值进行划分,划分为两部分,小于基准值的数据放在基准值左边,大于基准值的放在基准值右边,结束后继续按同样方法去划分。
以数组arr[]={ 6,3,1,9,6,7 }为例:
(1)第一次将所有数据看成一组排序一次(找到第一个数据排序后的位置)
(2)将基准数左边的数据看为一组,将基准数右边的数据看成一组分别再进行一次排序
(3)再将基准数左边的数据看为一组,将基准数右边的数据看成一组分别再进行一次排序,直到每个数组的数据只剩下1个数据。
2.代码实现
<1>.所需头文件和宏替换:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<stdbool.h>
#define ar arr[]={6,3,2,1,9,6,7}
#define ELEM_TYPE int
int ar;
<2>.顺序表的建立:
typedef struct Sqlist
{
ELEM_TYPE* data;
int length;
int SIZE;
}Sqlist,*PSqlist;
<3>.顺序表的初始化:
void Init_Sqlist(PSqlist L)
{
L->data = arr;
L->length = 0;
L->SIZE = sizeof(arr) / sizeof(arr[0]);
}
<4>.打印
void Show(PSqlist L)
{
for (int i = L->length; i < L->SIZE; i++)
{
printf("%d ", L->data[i]);
}
printf("\n\n");
}
<5>.获取基准值下标:(此函数面试经常会问到)
int partition(PSqlist L, int left, int right)
{
int tmp = L->data[left]; //将第一个数据看作基准值
while (left < right)
{
while (left < right && L->data[right]>=tmp) //从右向左找比基准值小的数据,放在基准值左边
{
right--;
}
if (left == right)
{
break;
}
L->data[left] = L->data[right]; //将小于基准值的数据放在基准值左边
while (left < right && L->data[left] <= tmp) //从左往右找比基准值大的数据,放在基准值右边
{
left++;
}
if (left == right)
{
break;
}
L->data[right] = L->data[left]; //将大于基准值的数据放在基准值右边
}
//此时退出最外层while循环,left == right 先将基准值插入这里,这个位置现在就是基准值的坐标(左边都小于基准值,右边都大于基准值)
L->data[left] = tmp;
return left;
}
<6>.每一次组划分:
void Quick(PSqlist L,int left,int right) //每一次快速排序
{
if (left < right) //保证至少有两个值
{
int par = partition(L, left, right); //获取基准值下标
//此时将整体数据分成了两个部分,基准值左边部分,和基准值右边部分
if (left < par - 1) //如果基准值左边部分至少还有2个值,则继续进行一次快速排序
{
Quick(L,left,par-1);
}
if (par + 1 < right) //如果基准值右边部分至少还有2个值,则继续进行一次快速排序
{
Quick(L, par + 1, right);
}
}
}
<7>.快速排序:
void QuickSort(PSqlist L) //先将初始数据排序一次
{
Quick(L,L->length,L->SIZE-1);
}
<8>.主函数:
int main()
{
Sqlist head;
Init_Sqlist(&head);
printf("初始数据为:");
Show(&head);
QuickSort(&head);
printf("快速排序后的数据为:");
Show(&head);
return 0;
}
<9>.运行结果:
希望这篇博客能帮助大家更好的学习和理解快速排序
感谢阅读!