快速排序(2)——快速排序的优化

因为Hoare的快速排序写起来容易出错,并且有很多地方不太合适,于是,就有了一下几种优化。

基准值的优化

如果我们一直选取一组数据的第一个数据为基准值,如果遇到重复少的值的化,没什么问题。但是如果重复的值比较多的化,就会造成一些重复,使得程序运行速度减慢。因此,我们可以优化一下基准值的取值。最常见的方法就是取begin 、 end、 和begin end中位数这三个下标对应的数中不大也不小的值。

代码如下:

int GetMidi(int* a, int begin, int end)
{
	int midi = (begin + end) / 2;
	// begin midi end 三个数选中位数
	if (a[begin] < a[midi])
	{
		if (a[midi] < a[end])
			return midi;
		else if (a[begin] > a[end])
			return begin;
		else
			return end;
	}
	else // a[begin] > a[midi]
	{
		if (a[midi] > a[end])
			return midi;
		else if (a[begin] < a[end])
			return begin;
		else
			return end;
	}
}

因此,我们更改一下快速排序

代码如下:

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;
	//注意一下
	int left = begin, right = end;

	int midi = GetMidi(a, begin, end);
	Swap(&midi, &begin);
	int keyi = begin;
	while (left < right)
	{
		//右边,找到比a[keyi]小的,然后放到左边
		//注意条件是<=
		while (left < right && a[keyi] <= a[right])
		{
			--right;
		}
		//左边,找到比a[keyi]大的,然后放到右边
		//注意条件是>=
		while (left < right && a[keyi] >= a[left])
		{
			++left;
		}
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);
	keyi = left;
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

挖坑法快速排序

挖坑法就是先将基准值存放在一个临时变量key中,形成一个坑位,然后右边找比key小的,然后放到原来的坑位,并且现在右边所处的位置形成一个新的坑位,然后左边开始找比key大的,然后找到后放到坑位,此时左边形成新的坑位,直到左右相遇。

图片实现

代码实现

int HoleSort(int* a, int begin, int end)
{
	int midi = GetMidi(a, begin, end);
	Swap(&a[midi], &a[begin]);
	int key = a[begin];
	int hole = begin;
	while (begin < end)
	{
		while (begin < end && a[end] >= key)
		{
			--end;
		}
		a[hole] = a[end];
		hole = end;
		while (begin < end && a[begin] <= key)
		{

			++begin;
		}
		a[hole] = a[begin];
		hole = begin;
	}
	a[hole] = key;
	return hole;
}
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;
	int keyi = HoleSort(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

前后指针法快速排序

前后指针法就是有一个prev 和 cur 。开始时,prev指向基准值,cur指针指向prev后面的一个位置。开始时,先判断cur的值是否小于k,若小于,prve++,然后交换prve和cur,然后cur++。然后cur继续进行,当cur的值小于key,然后prve++,当prve的值大于key,然后交换prve和cur的值,然后cur++。直到cur越界。此时交换key和prve的值,并且令key=prve。

图片实现

代码实现

int PSort(int* a, int begin,int end)
{
	int prve =begin , cur = prve+1;
	int midi = GetMidi(a, begin, end);
	Swap(&a[midi], &a[begin]);
	int key = begin;
	while (cur <= end)
	{
		if (a[cur] <= a[key]&&++prve!=cur)
			Swap(&a[cur], &a[prve]);
		cur++;
	}
	Swap(&a[prve], &a[key]);
	key = prve;
	return key;
}
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;
	int keyi = PSort(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

相关推荐

  1. 排序---快速排序4次优化

    2024-02-19 19:34:01       26 阅读
  2. 快速排序

    2024-02-19 19:34:01       51 阅读
  3. 排序算法——快速排序

    2024-02-19 19:34:01       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-19 19:34:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-19 19:34:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-19 19:34:01       82 阅读
  4. Python语言-面向对象

    2024-02-19 19:34:01       91 阅读

热门阅读

  1. Python编程读取csv文件数据分别计算RMSE、SD、R

    2024-02-19 19:34:01       52 阅读
  2. 面试题-02

    2024-02-19 19:34:01       45 阅读
  3. 浅析SpringBoot中的事务管理

    2024-02-19 19:34:01       58 阅读
  4. 力扣爆刷第74天--动态规划01背包

    2024-02-19 19:34:01       53 阅读
  5. 洛谷P5365 [SNOI2017] 英雄联盟

    2024-02-19 19:34:01       61 阅读
  6. 平台组成-内容管理

    2024-02-19 19:34:01       46 阅读
  7. 鸿蒙应用/元服务开发-窗口概述

    2024-02-19 19:34:01       55 阅读
  8. 链表 -02

    2024-02-19 19:34:01       56 阅读