【数据结构排序算法(八)】快速排序

基础数据结构之八大排序算法(八)快速排序

⑧快速排序(特点:数据越无序速度越快,时间复杂度越小)

递归:函数中自己调用自己)

时间复杂度: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[]={6321967}
#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>.运行结果:
在这里插入图片描述
希望这篇博客能帮助大家更好的学习和理解快速排序
感谢阅读!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逐梦的白鹰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值