当前位置: 首页 > news >正文

快速排序(hoare版本)

文章目录

文章目录

前言

二、使用步骤

1.实现基准值

2.递归实现排序

3.三数取中 

三.注意事项

总结


前言

我们之前学习的多种排序,它们都有着不同的效率,可以适用与不同的场景,接下来要说的一种排序它叫做快速排序,从它的名字就可以看出来它的效率一定很高。


一、快速排序的实现

        快速排序的实现就如图一样,先右边的开始走如果碰到比key值小的数值就在那个位置停下,然后左边开始执行,如果碰到比key值大的也同样停止,然后对两者进行交换。最后左和右相遇后将key和相遇的地方进行交换从而使得左边是比key小的值,右边是比key大的值,使用递归实现排序。

二、使用步骤

1.实现基准值

这是霍尔大佬最先发明写出的算法,同样的也是最经典的,同样的也好理解,通过交换的方法从而做到左边的比key要小,右边的比key要大。

代码如下(示例):

int Partsort(int* a, int left, int right)
{int begain = left;int end = right;int key = begain;while (begain < end){while (begain < end && a[end] >= a[key]){--end;}while (begain < end && a[begain] <=a[key]){++begain;}Swap(&a[begain], &a[end]);}Swap(&a[key], &a[begain]);return begain;
}

 

2.递归实现排序

通过递归的方式,我们可以使得数都满足左边的值大于右边从而实现排序。

代码如下(示例):

void qucksort(int* a, int left, int right)
{if (left >= right)return;int key = Partsort(a, left, right);qucksort(a, left, key - 1);qucksort(a, key + 1, right);
}

3.三数取中 

我们有时会因为key的值太小或者太大从而发挥不出快速排序的优势,所以我们可以使用自己的方式从而使其不会太大或者太小,所以三数取中就出现了,通过比较最左边和最右边以及中间的数来比较出那个的值是比较趋于中间的数。

int mid(int* a, int left, int right)
{int mid = (left + right) / 2;if (a[left] > a[right]){if (a[mid] > a[left]){mid = left;}else if (a[mid] < a[right]){mid = right;}}else if (a[left] < a[right]){if (a[mid] < a[left]){mid = left;}else if (a[mid] > a[right]){mid = right;}}return mid;}

三.注意事项

        我在编写代码的时候当时我认为我的思路都是正确的,代码写的也是正确的,但是就是无法实现排序,后面我发现了先走右边和先走左边是会对结果造成影响的,我最开始写的是从左边开始走,但是排序的结果是不正确的,从右边开始的话就正确了,因为我所设置的key就为数组的最左边,如果我先走左边的话,最后的结果就为当left和right相遇的时候就该进行交换了,而这个时候交换的话无法保证左边的数比key要小,因为先走左边的时候就会在比key的大的值位置停下,最后也只能在这个位置停下。

        所以实现排序的时候也要注意是先走的左边还是先走的右边,这样的小细节也是会影响到结果的实现。


总结

排序的方式有很多种,我们可以根据不同的实现场景来使用不同的代码,快速排序是一种效率很高的排序,很多函数内置的排序就是使用的快速排序,实现的原理并不困难,但是我们需要注意其中的细节,这样就可以省去不必要的麻烦。


http://www.mrgr.cn/news/58711.html

相关文章:

  • Android原生ROM出现WIFI显示网络连接受限,网络无法连接的问题
  • 实现vuex源码,手写
  • HarmonyOS鸿蒙- 一行代码自动换行技巧
  • P1443 马的遍历
  • 管理类联考 信息整理和经验分享
  • 今年2024的1024文章
  • 动态规划一>简单多状态系列
  • 在WebStorm遇到Error: error:0308010C:digital envelope routines::unsupported报错时的解决方案
  • It行业重点知识点详解操作系统学习方法
  • 什么是DSSA?
  • mysql建表
  • C#从零开始学习(GameObject实例)(unity Lab3)
  • C# LINQ 基础与应用
  • 判断特定时间点开仓的函数(编程技巧)
  • 如何提高游戏的游戏性
  • Flutter之build 方法详解
  • 创建插件 DLL 项目
  • Idea基于JRbel实现项目热部署修改Java、Xml文件无需重启项目
  • 【南方科技大学】CS315 Computer Security 【Lab6 IoT Security and Wireless Exploitation】
  • 文件下载漏洞
  • 东方博宜1180 - 数字出现次数
  • SPI通信(W25Q64)
  • nginx常规操作
  • MySQL8 配置密码和用户创建及授权详解:Java开发最佳实践
  • 【前端倒霉蛋--word导出】
  • 社交改运很简单:谋定而后动,三种人群的智慧策略,生成无敌贵人圈