快速排序

快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。快速排序算法的时间复杂度为O(nlogn)。由于关键字的比较和交换是跳跃进行的,因此,快速排序是一种不稳定的排序方法。

void QuickSort(SqList *L)
{
	QSort(L, 1, L->length);
}

void QSort(SqList *L, int low, int high)
{
	int pivot;
	if (low < high)
	{
		pivot = Partition(L, low, high);
		QSort(L, low, pivot - 1);
		QSort(L, pivot + 1, high);
	}
}

int Partition(SqList *L, int low, int high)
{
	int pivotkey;
	pivotkey = L->r[low];
	while (low <  high)
	{
		while (low < high && L->r[high] >= pivotkey)
			high--;
		swap(L, low, high);
		while (low < high && L->r[low] <= pivotkey)
			low++;
		swap(L, low, high);
	}
	return low;
}
Partition函数要做的,就是先选取当中的一个关键字,然后想尽办法把它放到一个位置,使得它左边的值都比它小,右边的值比它大,我们将这样的关键字称为 枢轴

快速排序的优化:
1、优化选取枢轴

三数取中法:即取三个关键字先进行排序,将中间数作为枢轴,一般是取左端、右端和中间三个数。

//优化选取枢轴
int pivotkey;
int m = low + (high - low) / 2;
if (L->r[low] > L->r[high])
	swap(L, low, high);
if (L->r[m] > L->r[high])
	swap(L, m, high);
if (L->r[m] > L->r[low])
	swap(L, m, low);
pivotkey = L->r[low];
2、优化不必要的交换

//优化不必要的交换
int Partition1(SqList *L, int low, int high)
{
	int pivotkey;
	pivotkey = L->r[low];
	L->r[0] = pivotkey;
	while (low <  high)
	{
		while (low < high && L->r[high] >= pivotkey)
			high--;
		L->r[low] = L->r[high];
		while (low < high && L->r[low] <= pivotkey)
			low++;
		L->r[high] = L->r[low];
	}
	L->r[low] = L->r[0];
	return low;
}

3、优化小数组时的方案

如果数组非常小,其实快速排序反而不如直接插入排序来得更好。增加一个判断,当high-low不大于某个常数时(有资料认为7比较合适),就用直接插入排序。

#define MAX_LENGTH_INSERT_SORT 7
void QSort(SqList *L, int low, int high)
{
	int pivot;
	if ((high - low) > MAX_LENGTH_INSERT_SORT)
	{
		pivot = Partition(L, low, high);
		QSort(L, low, pivot - 1);
		QSort(L, pivot + 1, high);
	}
	else
		InsertSort(L);
}
4、优化递归操作

//优化递归操作
void QSort1(SqList *L, int low, int high)
{
	int pivot;
	if ((high - low) > MAX_LENGTH_INSERT_SORT)
	{
		while (low < high)
		{
			pivot = Partition1(L, low, high);
			QSort1(L, low, pivot - 1);
			low = pivot + 1;
		}
	}
	else
		InsertSort(L); 
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值