No.3 快速排序

桶排序,浪费空间,冒泡排序,时间复杂度高,“快排”应该是一种比较好的排序算法,既省空间又降低了时间复杂度,它的时间复杂度是O(Nlog⁡N),但是在最坏的情况下它的时间复杂度和冒泡排序一样为O(N^2)。

假设我们要给“8 2 3 5 1 6 4 10 9 7”这样一组数排序,利用“快排”。首先从这组数中选出一个数作为基准数,通常我们选择第一个数,然后我们需要将这个序列中所有比基准数大的数放在基准数的右边,比基准数小的数放在基准数的左边。

在此序列中,我们选8作为基准数,先从右往左找找一个比8小的数,再从左往右找找一个比8大的数,然后把这两个数进行交换。定义两个变量i和j,分别指向序列的最左边的数8和最右边的数7,然后从右往左找(j–)直到找到一个比8小的数,然后从左往右找一个比8大的数(i++)直到找到一个比8大的数,最后j指向7,i指向10,交换7和10,交换后序列为“8 2 3 5 1 6 4 7 9 10”,然后j继续向左找(j–),最后指向7,但是此时i和j指向同一个位置,所以要将7和基准数8进行交换,让基准数归位,第一轮结束后序列为“7 2 3 5 1 6 4 8 9 10”,以8为分界点,再分别对8左边的数和右边的数进行上述操作,直到出现不可拆分的新的子序列为止,即所有的数均按要求排好。用c还是很容易实现的,不过程序好像有点问题,不是bug,没有报错,它就是傲娇地不想排而已。

#include<stdio.h> 

int a[100];//定义一个数组用于存储要排序的数 
void quicksort(int left,int right){
	int i,j,t,temp;//temp用于临时存储选定的基准数 
	if(left>right) 
	   return;
	
	temp=a[left];//选定要排序序列最左边的数作为基准数并存储在变量temp中 
	i=left;//i,j分别处于序列的最左边和最右边的位置 
	j=right;
	
	while(i!=j){
		//从右边向左边开始找 
		while(a[j]>=temp && i<j)//右边存在比基准数大的数且i<j 就一直从右往左找,直到找到一个数比基准数小就停下来
		       j--;
		while(a[i]<=temp && i<j)//再从左往右找,直到找到一个数比基准数大就停下来 
		       i--;
	   
	   if(i<j){//从右往左找找到了一个数比基准数小且从左往右找找到了一个比基准数大的数,且此时i,j并不相等,就将这两个数交换 
	   	   t=a[i];
	   	   a[i]=a[j];
	   	   a[j]=t;
	   }
	  } 
	  //当i=j时让基准数归位 
	   a[left]=a[i];
	   a[i]=temp;
	   
	   quicksort(left,i-1);//利用递归,给基准数左边的序列排序 
	   quicksort(i+1,right);//利用递归,给基准数的右边的序列排序 
	   return; 
}
int main(){
	int i,j,n;
	scanf("%d",&n);//要排序数字的个数 
	for(i=1;i<=n;i++)
	   scanf("%d",&a[i]);
    
    quicksort(1,n);//调用quicksort函数 
	for(i=1;i<=n;i++)
	   printf("%d ",a[i]);
	
	getchar();getchar(); 
	return 0; 
}

“快排”比冒泡排序快是因为它每次交换都是跳跃式的,而冒泡排序每次只能让相邻的进行交换,所以“快排”交换次数少,效率高,但是最坏的情况就是每次只能交换相邻的数,这就和冒泡排序一样了。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值