【C语言】快速排序的优化--简单易懂

一、分析快速排序的时间复杂度:

最优的情况:

每次选到的基准值能把待排序的的数组平均分

这种情况下的时间复杂度为  O(𝑛log⋅𝑛)

最差的情况:

每次选到的数都是最小或着最大的数

只是把数组分成了( 空 基准值 n-1) 三个部分

这样情况下的时间复杂度为 O(𝑛^2)


具体的分析请看下图:

二、解决问题

通过上图我们发现是由于基准值的选择而导致了效率的不稳定

那我们就对之前选数的方法进行修改

1)两种修改方法

1.随机选数(随机选择数字作为基准值)

2.三数取中(在left right  mid 中取中间值为基准值)

2)代码实现

******************************************随机选数***********************************************

//随机选数
int randKey(int* a, int left, int right)
{
	int r = rand() % right+1;//0~right
	int rKey = r >= left ? r : r + (right - left)+1;
	return rKey;
}

******************************************三数取中************************************************

//三数取中
int Midi(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	//left>=mid
	if (a[left] >= a[mid])
	{
		//left>=mid>=right
		if (a[mid] >= a[right])
			return mid;
		//left ? right >mid
		else if (a[left] > a[right])
			return right;
		else
			return left;
	}
	//left<mid
	else
	{
		//left<mid<right
		if (a[mid] <= a[right])
			return mid;
		else if (a[right] >= a[left])
			return right;
		else
			return left;
	}
}

三、新的问题

1)问题分析

如果数组中的值全部相等或存在大量相同的数,那么上面两种方法的优化就十分微弱

时间时间效率会向最坏的方向走。

我们之前是把数组分为 【小于】 【大于】

如果有大量相同的数我们就应再加一个区间  【大于】 【等于】 【小于】

2)代码实现

代码的实现结合了最基本的方法和前后指针法

不会的同学可以看这里:

基本方法:

http://t.csdnimg.cn/a4Rb0

前后指针法:

http://t.csdnimg.cn/HT5Fx

//三段区间
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;


	int key = a[begin];
	int left = begin;
	int right = end;
	int cur = left + 1;
	while (cur<=right)
	{
		if (a[cur] > key)
		{
			Swap(&a[cur], &a[right]);
			right--;
		}
		else if (a[cur] < key)
		{
			Swap(&a[cur], &a[left]);
			cur++;
			left++;
		}
		else
		{
			cur++;
		}
	}

	// begin left  right  end
	QuickSort2(a, begin, left-1);
	QuickSort2(a, right+1, end);
}

四 、结语

以上就是对快速排序的优化,若有错误,还望指出。

关于快速排序,作者的主页有着详细的介绍,包括三种不同的方法。

你的点赞和关注是作者前进的动力!

最后,作者主页有许多有趣的知识,欢迎大家关注作者,作者会持续更新有意思的代码,在有趣的玩意儿中成长!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值