C语言之快速排序

今天来讲下快速排序的实现逻辑和代码。

逻辑:

1.首先选取一个无序序列的某个数值作为中值prvot;

2.将大于prvot的数值排放在prvot的右边,小于i的放左边;

3.将prvot左侧和右侧的数值再次进行排放,直到个数为1.

到这时排序也就结束了;

这个排序体现了什么思想呢?——————就是分治和递归。

为了方便代码的实现,我们现在每次都把第一个数值作为prvot;


1.先写出主函数

int main()
{
	int arr[1000] = { 0 }, n,i;
		scanf("%d",&n);            //数组大小
		for (i = 0; i < n; i++)
		{
			scanf("%d", &arr[i]);  //进行输入
		}
	quick(arr, 0, n-1);            //进行排序
	for (i = 0; i < n; i++)
		printf("%d ", arr[i]);     //输出结果
	return 0;
}

2.快速排序的基本逻辑:

我们先只看单次排序:

我们任意拿五个数

 定义一个变量prvot,将首个数值放进prvot,然后我们默认首个位置是没有数值的,这样便于观察理解,反正值是会改变的,不会影响代码的实现。

顺便再在首尾定义两个指针,便于改变数值,首先从R开始比较,5>3所以我们不动5,再将R向左移动

 

 

这时我们发现1<3,那么我们将1放入最左边,并且将L向右移动(因为L的位置与5一样,是排过序的)。

交换对比的指针。现在从L边看起、

发现8>3,所以我们把8放在R所指的位置,并将R向左移动。

 

 重复进行比较我们会发现L总会和R重合。

然后把prvot的值赋在该处。

 再对左右两侧进行排序,直到个数为1,就像图中左侧只有1了,是最小的不用排序,右侧的数值未处理,需要再次排序。


这是单次排序的代码

void quick(int arr[], int left, int right)
{

	int prvot = arr[left], flag = 1;        //    prvot放中轴值,flag来切换指针的运动
	int* L = &arr[left], * R = &arr[right];
	while (L < R)
	{
		if (flag)
		{
			if (*R >= prvot)
				R--;
			else
			{
				*L = *R;
				L++;
				flag = 0;
			}
		}
		else
		{
			if (*L <= prvot)
				L++;
			else
			{
				*R = *L;
				R--;
				flag = 1;
			}
		}

	}
	*L = prvot;

}

我们现在需要再次进行排序,直到个数为一,我们就此出发进行编写。

int i;	
for (i = 0; i < right; i++)
		if (arr[i] == prvot)
			break;                //寻找中轴值的下标
	quick(arr, left, i - 1);      //对两边进行排序
	quick(arr, i + 1, right);

​

最后我们需要设置停止的条件,我们知道要让个数为1,就意味着让quick中的left>right(注意是大于不是等于应为再函数运行完后我们传参传的是i-1,最后两边是无法等于的)

	if (left > right)
		return;

最后拼接修改起来就是

#define maxn 100
#include<stdio.h>
void quick(int arr[], int left, int right)
{
	if (left > right)
		return;
	int prvot = arr[left], flag = 1, i;
	int* L = &arr[left], * R = &arr[right];
	while (L < R)
	{
		if (flag)
		{
			if (*R >= prvot)
				R--;
			else
			{
				*L = *R;
				L++;
				flag = 0;
			}
		}
		else
		{
			if (*L <= prvot)
				L++;
			else
			{
				*R = *L;
				R--;
				flag = 1;
			}
		}

	}
	*L = prvot;
	for (i = 0; i < right; i++)
		if (arr[i] == prvot)
			break;
	quick(arr, left, i - 1);
	quick(arr, i + 1, right);
}

int main()
{
	int arr[maxn] = { 0 }, n,i;
		scanf("%d",&n);
		for (i = 0; i < n; i++)
		{
			scanf("%d", &arr[i]);
		}
	quick(arr, 0, n-1);
	for (i = 0; i < n; i++)
		printf("%d ", arr[i]);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

昨今非是

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

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

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

打赏作者

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

抵扣说明:

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

余额充值