快速排序的多种方法与详解,非递归与递归和改进

快速排序的实现

  • 三数取中打乱数据
int getmi(int* a, int l, int r)
{//三者取中
	int mid = (l + r) / 2;
	if (a[mid] > a[l])
	{
		if (a[mid] < a[r])
			return mid;
		else if (a[r] > a[l])
			return r;
		else
			return l;	
	}
	else
	{
		if (a[mid] > a[r])
			return mid;
		else if (a[r] > a[l])
			return l;
		else
			return r;
	}
}
  • hoare方法
    注:l与r的先后遍历与排序方式相关,从小到大先遍历r,反之
int PartSort1(int* a, int left, int right)
{
	int mid = getmi(a, left, right);
	Swap(&a[mid], &a[left]);
	int k = a[left];
	int l = left+1;
	int r = right;
	while (l < r)
	{
		while (l<r&&a[r] >= k)
			r--;
		while (l<r&&a[l] <= k)
			l++;
		Swap(&a[l], &a[r]);
	}
	Swap(&a[l], &a[left]);
	return l;
}
  • 挖坑法
    注:一定要先讲以一个坑的值进行存储
int PartSort2(int* a, int left, int right)
{

	int mid = getmi(a, left, right);
	Swap(&a[mid], &a[left]);
	int k = a[left];
	int hole = left;
	int l = left + 1;
	int r = right;
	while (l < r)
	{
		while (l<r && a[r]>=a[hole])
			r--;
		a[hole] = a[r];
		hole = r;
		while (l < r && a[l] <= a[hole])
			l++;
		a[hole] = l;
		hole = l;
	}
	a[hole] = k;
	return hole;
}
  • 前后指针法
    注: 使用前后指针,将小的置换到前面去
int PartSort3(int* a, int left, int right)
{
	int mid = getmi(a, left, right);
	Swap(&a[mid], &a[left]);
	int k = a[left];
	int l = l ;
	int c = l+1;
	while (c <= right)
	{
		if (a[c] < k && ++l != c)
		{
			Swap(&a[c], &a[l]);
		}
		c++;
	}
	Swap(&a[l], &a[left]);
	return l;
}
  • 使用递归实现
void QuickSort(int* a, int left, int right)
{
	if (left >= right)
		return;
	if (right - left + 1 < 10)
	{
		InsertSort(a, right - left + 1);
	}
	else
	{
		int k=PartSort1(a, left, right);
		QuickSort(a, left, k - 1);
		QuickSort(a, k+1,right);
	}
}
  • 非递归实现
    注:利用栈的性质去实现,插入的左右顺序一定要一直保持一致
void QuickSortNonR(int* a, int left, int right)
{
	stack<int>sta;
	sta.push(right);
	sta.push(left);
	while (sta.empty())
	{
		int l = sta.top();
		sta.pop();
		int r = sta.top();
		sta.pop();
		int k = PartSort1(a, l, r);
		if (k + 1 < r)
		{
			sta.push(r);
			sta.push(k + 1);
		}
		if (l < k - 1)
		{
			sta.push(k - 1);
			sta.push(l);
		}
	}
}

改良升级版
将数据分成三个部分,小于等于和大于,这样对于有重复数据的时候处理更快

void quicksort3(int* a, int b, int e)
{
	if (b >= e)
		return;
	int l = b;
	int r = e;
	int c = l + 1;
	int mid = getmi(a, b, e);
	Swap(&a[l], &a[mid]);
	int k = a[l];
	while (c <= r)
	{
		if (a[c] < k)
		{
			Swap(&a[l], &a[c]);
			c++;
			l++;
		}
		else if (a[c] > k)
		{
			Swap(&a[r], &a[c]);
			r--;
		}
		else
			c++;
	}
	quicksort3(a, b, l);
	quicksort3(a, r + 1, e);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值