快速排序算法

题目描述:

给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。

本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:

数据1:只有1个元素;
数据2:11个不相同的整数,测试基本正确性;
数据3:10^3个随机整数;
数据4:10^4个随机整数;
数据5:10^5个随机整数;
数据6:10^5个顺序整数;
数据7:10^5个逆序整数;
数据8:10^5个基本有序的整数;
数据9:10^5个随机正整数,每个数字不超过1000。
输入格式:

输入第一行给出正整数N(≤10​^5​​ ),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。

输出格式:

在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。

输入样例:

11
4 981 10 -17 0 -20 29 50 8 43 -5

输出样例:

-20 -17 -5 0 4 8 10 29 43 50 981

解题思路:

看到10^5后,孩子脑子里只剩下快排了。不要问为什么……想想空间,想想时间。
首先,咱们说说快排的思想:通过一次排序,将要排序的数据分割成两个部分,其中一部分的数据比另一部分的数据都要大。然后再按次方法对这两部分数据分别进行快速排序,然后进行递归,从而使整个数据变成有序数列。
可能这样说大家有点不明白哈!下面给大家文字详解一下。。。。

  1. 首先我们要选一个数据作为参考数,将大于它的放右边,小于它的放左边。(一般是指定第一个元素)
  2. 然后设置两个变量 i,j i 为第一个元素的下标,j 为最后一个元素的下标。
  3. 然后用变量 t 记录下第一个元素,及 t=a[0]
  4. 接着 j 往前扫描,每次 j 都产生自减。直到找到一个小于 t 的值,然后两者进行互换。
  5. 当然 i 往后扫描,每次 i 都产生自加。直到找到一个大于 t 的值,然后两者进行互换。每次换完后要记得break终止哦!!!!
  6. 然后便进入一个大循环重复以上操作,直到 i > j 后,便算完成一次排序啦!!

咳咳,接下来按照题目给的输入输出,给大家跑一趟:
在这里插入图片描述
接着 j t 进行比较,发现 -5 小于 4 ,所以直接将 -5 扔前面去,然后终止。 i t 进行比较, -5 不大于 4 ,所有往右走,发现 981 大于 4 ,所以将 981 扔后面去。一次内部小循环运行完后,将 t 归位。及 a[i]=t
在这里插入图片描述
然后重复此操作,一直比较到 i 不再小于 j 时 便算完成一次快速排序。

在这里插入图片描述
接下就便是对余下的部分进行分开递归。最终使数列达到有序。
刚刚开始打完的时候感觉太复杂了,经过反复的优化,感觉这应该是最好记忆滴啦!
这浓浓的对称美。。。。啊哈哈哈哈哈
总的来说,快速算法还是很重要的,大家最好还是能够背下来,以防不时之需。

话不多说,代码奉上:

#include<stdio.h>
int fun(int a[],int n)
{
	int i,j,t;
	i=0;                      //记录第一个元素的下标
	j=n-1;					  //记录最后一个元素的下标
	if(n<=0)return 0;
	t=a[0];					  //拍照技术,被压了以后好复原,也是作为标准数
	while(i<j)
	{
    	while(i<j)			
    	{
	    	if(t>a[j]){a[i]=a[j];break;}
	    	j--;			  //j不停的往前扫描
		}
		while(i<j)
		{
	    	if(t<a[i]){a[j]=a[i];break;}
	    	i++;			  //i不停的往后扫描
		}
		a[i]=t;
	}
	fun(a,i);				  //对前半部分进行递归
	fun(a+i+1,n-i-1);		  //对后半部分进行递归 
}
int main()
{
	int a[101100],n,i;
	scanf("%d",&n);
	for(i=0;i<n;i++)scanf("%d",&a[i]);
	fun(a,n);
	for(i=0;i<n;i++)
	{
		printf("%d",a[i]);
		if(i+1!=n)printf(" ");
	}
	return 0;
}

新手上道,大神请飘过。。。。。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木木不会

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

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

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

打赏作者

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

抵扣说明:

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

余额充值