快速排序思想及实现

devtools/2024/9/24 18:50:20/

思想(从小到大排序)

总体

对数组进行分区,选定一个元素作为基准,然后将小于基准的元素放在基准的左边,将大于基准的元素放在基准右边,分区完成之后再对左边的元素和右边的元素分别进行分区,直到左右区间不可再分。这采用了分治的思想,使排序速度加快。

分区(分治)

首先,将基准元素放在数组左端;
接着,使用两个指针(此处的指针其实是数组元素的索引),右指针从数组尾部向数组头部寻找小于基准的元素,左指针从数组头部向数组尾部寻找大于的基准的元素,在寻找的过程中,左指针不能超过右指针。找到这两个指针后,交换其指向的元素;
最后,将基准与小于基准元素的最后一个元素进行交换,从而实现这样的效果:[小于基准的元素们, 基准, 大于基准的元素们]

寻找基准

实际上,寻找基准也不是一个简单的事,以下有两种策略:

策略一

将待排序区间的左端点作为基准。但这样简单的实现有一个缺点:如果数组的值为从大到小排列,则每次分区都左区间都是空区间,右区间是除已有的基准元素们外的所有剩余元素,这样就会使快速排序降级为冒泡排序。

策略二

找到待排序区间中左端点值、右端点值和中间端点值的中位数。这样就避免了基准元素极度不均衡的问题,就算这三个数分别是最大值、第二大值、第三大值,也能选出一个第二大值来,从而左区间就不可能是空区间了。寻找中位数的原理可以看这篇文章:寻找中位数。

代码实现

C

// 寻找中位数
int medianThree(int arr[], int left, int mid, int right) {int a = arr[left], b = arr[mid], c = arr[right];if ((a < b) ^ (a < c)) {return left;} else if ((b < a) ^ (b < c)) {return mid;} else {return right;}
}
// 交换元素
void swap(int arr[], int i, int j) {int t = arr[i];arr[i] = arr[j];arr[j] = t;
}
// 分区
void partition(int arr[], int left, int right) {if (left >= right) { // 如果子区间长度为0或为负数,则退出递归return;}int p = medianThree(arr, left, (left + right) >> 1, right); // 寻找基准的索引swap(arr, left, p); // 让基准成为区间左端点int i = left + 1, j = right;while (i < j) {while (arr[j] >= arr[left] && i < j) { // 寻找小于基准的元素j--;}while (arr[i] <= arr[left] && i < j) { // 寻找大于基准的元素i++;}swap(arr, i, j); // 交换这两个元素}swap(arr, left, i); // 让基准成为区间的分界线,i指向最后一个小于基准的元素partition(arr, left, i - 1); // 对左子区间进行分区partition(arr, i + 1, right); // 对右子区间进行分区
}
// 快速排序
void quickSort(int arr[], int len) {partition(arr, 0, len - 1);
}

Java

java">class Sort {public static void sort(int[] arr) {partition(arr, 0, arr.length - 1);}private static void partition(int[] arr, int left, int right) {if (left >= right) { // 如果子区间长度为0或为负数,则退出递归return;}int p = medianThree(arr, left, (left + right) >> 1, right); // 寻找基准的索引swap(arr, left, p); // 让基准成为区间左端点int i = left + 1, j = right;while (i < j) {while (arr[j] >= arr[left] && i < j) { // 寻找小于基准的元素j--;}while (arr[i] <= arr[left] && i < j) { // 寻找大于基准的元素i++;}swap(arr, i, j); // 交换这两个元素}swap(arr, left, i); // 让基准成为区间的分界线,i指向最后一个小于基准的元素partition(arr, left, i - 1); // 对左子区间进行分区partition(arr, i + 1, right); // 对右子区间进行分区}private static void swap(int[] arr, int i, int j) {int t = arr[i];arr[i] = arr[j];arr[j] = t;}private static int medianThree(int[] arr, int left, int mid, int right) {int a = arr[left], b = arr[mid], c = arr[right];if ((a < b) ^ (a < c)) {return left;} else if ((b < a) ^ (b < c)) {return mid;} else {return right;}}
}

http://www.ppmy.cn/devtools/23650.html

相关文章

sky13笔记

1.generate用法 generate是物理上的展开&#xff0c;在compile时完成展开。 e.g.把array里面的每一项放入scale&#xff1a; wire [7:0] array [0:7]; wire [8*8-1 :0]scale; generate genvar gen_x; for(gen_x 0; gen_x <8; gen_x gen_x 1)begin:gen_scaleassign scale[ge…

vue3使用echarts做树图tree

vue3使用echarts做树图tree 1.安装echarts npm install echarts --save2.在main.js引入 import * as echarts from echarts // 全局方法 app.config.globalProperties.$echarts echarts3.使用 <div id"myChart" :style"{ width: 1000px, height: 1000px …

信号分解 | SSA(奇异谱分析)-Matlab

分解效果 SSA(奇异谱分析) 信号分解 | SSA(奇异谱分析)-Matlab 奇异谱分析(Singular Spectrum Analysis,简称SSA)是一种用于时间序列分析的方法。它可以用于数据降维、信号分解、噪声去除和预测等应用。 SSA的基本思想是将时间序列分解为若干个成分,每个成分代表着不同的…

【Redis | 第十篇】Redis与MySQL保证数据一致性(两种解决思路)

文章目录 10.Redis和MySQL如何保证数据一致性10.1双写一致性问题10.2数据高度一致性10.3数据同步允许延时10.3.1中间件通知10.3.2延迟双删 10.Redis和MySQL如何保证数据一致性 10.1双写一致性问题 Redis作为缓存&#xff0c;它是如何与MySQL的数据保持同步的呢&#xff1f;特…

基于知识图谱的大学生就业能力评价和职位推荐系统——超详细要点总结(创作不易,还请点赞)

1. 职位节点&#xff08;Position&#xff09;&#xff1a; 软件工程师 数据科学家 系统架构师 网络安全专家 人工智能工程师 嵌入式系统工程师 物联网工程师 大数据工程师 前端/后端开发工程师 云计算工程师 区块链工程师 自然语言处理专家 软件测试工程师 人机交…

【智能优化算法】樽海鞘群算法(Salp Swarm Algorithm,SSA)

樽海鞘群算法(Salp Swarm Algorithm&#xff0c;SSA)是期刊“Advances in Engineering Software ”&#xff08;中科院二区&#xff0c;IF 7.0&#xff09;的2017年智能优化算法 01.引言 樽海鞘群算法(Salp Swarm Algorithm&#xff0c;SSA)&#xff0c;用于解决单目标的优化问…

笔记:能量谱密度与功率谱密度(二)

目录 一、ESD与PSD的定义、单位、性质 二、对ESD与PSD的直观理解 三、总结&#xff1a; 某物理量的“分布”在离散系统中&#xff0c;各点(纵坐标含义&#xff09;的物理意义仍然是该物理量&#xff0c;而在连续系统中&#xff0c;各点&#xff08;纵坐标含义&#xff09;的物…

【C++初阶】string

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…