快速排序及改进

#include<bits/stdc++.h>
using namespace std;
int Partition(int a[],int l,int r) //原版
{
	int k=a[l];
	while(l<r)
	{
		while(l<r&&a[r]>=k)r--;
		a[l]=a[r];
		while(l<r&&a[l]<=k)l++;
		a[r]=a[l];
	}
	a[l]=k;
	return l;
}
int Partition2(int a[],int l,int r)//改进版,即取l、mid、r对应值中的中间值作为数轴元素 
{
	int mid=(l+r)/2;
	int k1=a[l],k2=a[mid],k3=a[r];
	int k;
	if(k1>=min(k2,k3)&&k1<=max(k2,k3))
	{
		k=k1;
	}
	else if(k3>=min(k2,k1)&&k3<=max(k2,k1))
	{
		k=k3;
		while(l<r&&a[l]<=k)l++;
		a[r]=a[l];
	}
	else
	{
		k=k2;
		while(l<r&&a[l]<=k)l++;
		a[mid]=a[l];
	}

	while(l<r)
	{
		while(l<r&&a[r]>=k)r--;
		a[l]=a[r];
		while(l<r&&a[l]<=k)l++;
		a[r]=a[l];
	}
	a[l]=k;
	return l;
}
void QuickSort(int a[],int l,int r)
{
	if(l>=r)return;
	int p=Partition2(a,l,r);
	QuickSort(a,l,p-1);
	QuickSort(a,p+1,r); 
}

int main()
{
	int a[]={5,3,4,1,2};
	QuickSort(a,0,4);
	for(int i=0;i<5;++i)
		cout<<a[i]<<" "; 
} 

快速排序算法有多种改进方法,以下为你介绍常见的几种: - **三数取中法**:在快速排序中,基准值的选择对算法性能影响较大。若基准值选择不当,可能导致分割的两部分数据极度不平衡,使算法性能下降。三数取中法通过选取数组首、尾和中间位置的三个元素,将这三个元素排序后取中间值作为基准值,这样能让基准值更接近数组的中间大小,使分割更平衡。例如,在处理数组`[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]`时,选取`3`、`5`和`2`这三个元素,排序后为`2`、`3`、`5`,取中间值`3`作为基准值。 - **小数组使用插入排序**:当数组长度较小时,快速排序的递归调用开销较大,而插入排序在小规模数据上性能较好。因此,当子数组长度小于某个阈值(如 10)时,使用插入排序来处理这些小数组,能减少递归调用次数,提高算法效率。如在快速排序过程中,当某个子数组长度为 8 时,就采用插入排序对其进行排序。 - **挖坑法**:挖坑法是一种改进的分区方式。它先选取一个基准值,将其位置作为初始的“坑”,然后从数组两端向中间扫描,把符合条件的元素填入“坑”中,并产生新的“坑”,直到左右指针相遇,最后将基准值填入最终的“坑”中。以下是挖坑法实现快排的代码示例: ```cpp template<class T> // 插入排序 void CC_InsertSort(T* begin, int Len) { T t, * A = begin; int i, j; for (i = 1; i < Len; i++) if (A[i] < A[i - 1]) { t = A[i]; for (j = i - 1; j >= 0 && A[j] > t; j--) A[j + 1] = A[j]; A[j + 1] = t; } } template<class T> // 挖坑快速排序 int partition(T* begin, int Len) { T* A = begin; T Tem = A[0]; // 选取比较的基准,其位置也就是初始的坑位 int i = 0, j = Len - 1; while (i < j) { while (A[j] >= Tem && i < j) j--; if (i < j) A[i++] = A[j]; while (A[i] <= Tem && i < j) i++; if (i < j) A[j--] = A[i]; } A[j] = Tem; return j; } template<class T> void CC_QuickSort(T* A, int Len) { if (Len <= 1) return; int k = partition(A, Len); CC_QuickSort(A, k); CC_QuickSort(&A[k + 1], Len - k - 1); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值