算法:快速排序算法

    快速排序的思想是:选取一个枢轴值,一趟排序后,将待排序列分成两部分,左边部分均不大于这个枢轴值,右边部分均不小于这个枢轴值。然后再次对两侧进行快速排序,直至整个序列有序。

实例:

#include "stdio.h"
#define MAXSIZE 10

int data[MAXSIZE] = {5,4,3,6,8,1,2,9,7,0};

void swap(int data[],int i,int j)
{
	int temp = data[i];
	data[i] = data[j];
	data[j] = temp;
}

/*
*	功能:将一个数据插到一个左边不大于,右边不小于他的位置
*	输入:1.排序数组;2.数组下标;3.数组上标
*	输出:上面功能提及的那个位置
*/
int partition(int data[],int low,int high)
{
	int pivotkey = data[low];  // 选取第一个元素为枢轴值
	while(low < high)  // 条件都为当下标小于上标,通过移动两个游标,当两者相等时就是该枢轴返回的位置。
	{
		while(low < high && data[high] >= pivotkey)  // 当右侧元素大于等于枢轴值时,上标--
			high--;
		swap(data,low,high);  // 否则交换位置
		while(low < high && data[low] <= pivotkey)  // 交换后的第一个判断一定成立,当左侧元素小于等于枢轴值时下标++
			low++;
		swap(data,low,high);  // 否则交换位置
	}  // 直至枢轴值插到一个左边不大于,右边不小于他的位置
	return low;
}

/*
*	功能:快速排序
*	输入:1.排序数组;2.数组下标;3.数组上标
*	输出:无
*	算法:将一个数放在一个左边不大于它右边不小于它的位置,然后不断递归
*/
void quickSort(int data[],int low,int high)
{
	int pivot;
	if(low < high)
	{
		pivot = partition(data,low,high);  // 返回枢轴值所在位置
		quickSort(data,low,pivot-1);   // 再次对左侧分组进行快速排序
		quickSort(data,pivot+1,high);  // 再次对右侧分组进行快速排序
	}
}	

void print(int *data)
{
	for(int i = 0; i < MAXSIZE; i++)
		printf("%d ",data[i]);
	printf("\n");
}

void main(int argc, char* argv[])
{
	print(data);
	quickSort(data,0,MAXSIZE-1);	
	print(data);
}
打印结果:



优化:

①优化选取枢轴值

固定选取第一个元素作为枢轴是不太合理的,因为待排序的序列可能是常常是基本有序的。partition函数显然会做了大量的无用功,很可能成为性能的瓶颈。

方法:三数取中,取三个元素的中间值作为枢轴。最方便的做法就是选取左右两端以及中间三个数的中间值。

int pivotkey;  

/*三数取中以获得较好的枢轴值*/
int m = low + (high-low)/2;
if(data[low] > data[high])
	swap(data,low,high);
if(data[m] > data[high])
	swap(data,m,high);
if(data[m] > data[low])
	swap(data,m,low);

pivotkey = data[low];  // 选取一个数值尽量靠中间的为枢轴
②优化不必要的交换

while(low < high)  
{
	while(low < high && data[high] >= pivotkey)  
		high--;
	data[low] = data[high];  // 直接赋值取代了交换
	while(low < high && data[low] <= pivotkey) 
		low++;
	data[high] = data[low];
}  
data[low] = pivotkey; 
③优化递归操作,递归对性能无疑有一定影响,尤其是在递归深度越深时。

while(low < high)
{
	pivot = partition(data,low,high);  // 返回枢轴值所在位置
	quickSort(data,low,pivot-1);   // 再次对左侧分组进行快速排序
	low = pivot+1;  // low此时没用了,用迭代来取代递归,缩减堆栈的深度
}
做了一个小测试,选的值都是比较适中的。因为测试的都是随机数,所以第一个优化基本无效,第二个优化就是这次比较的结果,第三个优化应该对时间性能上影响不大。



    快速排序法的平均时间复杂度是O(nlogn)




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值