当前位置:网站首页>排序——快速排序(快慢指针实现)
排序——快速排序(快慢指针实现)
2022-07-28 09:54:00 【Schuyler_yuan】
之前总结过快排的两种解法,可以参考快排的两种常见解法,最近又发现一种更容易理解的方法,在这里做下记录。
这是一种使用 “快慢指针比较” 的方法,来实现快速排序算法。
实现快速排序算法的关键,先在数组中选择一个数字(可以理解为轴值),把数组中的数字分为两部分,比选择的数字小的数字移到数组的左边,比选择的数字大的数字移到数组的右边。
int partition(vector<int>& nums, int start, int end) {
int index = (start + end) / 2;
swap(nums, index, end);
int small = start - 1;
for (index = start; index < end; ++index) {
if (nums[index] < nums[end]) {
++small;
if (small != index) {
swap(nums, small, index);
}
}
}
++small;
swap(nums, small, end);
return small;
}解释:
这里的快慢指针,index是快指针,small是慢指针,
慢指针指向的位置,其元素都是比轴值大,当快指针和轴值比较,对应的值比轴值小时,交换快指针和慢指针的值,就是把小的放在前面,快慢指针相同时,不用交换,
因为上次交换完,small指向的是上次交换完的结果,比轴值要小,把慢指针small往后移动一个,本次交换要把快指针index指向的新小元素挪到前面,如果small等于index就不用交换,如果small不等于index,在small和index之间的元素必定要比轴值大,所以可以实现,把小的元素放在前面,把大的元素放在后边,如果听到这里还不清楚,建议自己画图,实际走一遍。
确保慢指针从-1开始,最后再加回来,其上的值和轴值最后交换,完成一轮partition。
边缘条件
如果首次随机index对应的值是最大的数,一轮partition只把最大的数调到了最后,
如果首次随机index对应的值是最小的数,一轮partition只把最小的数调到了最前。
完整例子
例子:65,58,95,10,57,62,13,106,78,23,85
#include<vector>
#include<iostream>
#include<cstdlib>
using namespace std;
void swap(vector<int>& nums, int one, int two) { // 交换操作
int temp = nums[one];
nums[one] = nums[two];
nums[two] = temp;
}
int partition(vector<int>& nums, int start, int end) { // 一轮数组分割
int index = (start + end) / 2; // 最科学的方法是随机选择轴值,这里选择中值也是可以的
swap(nums, index, end); // 把轴值放在数组的最后,完成一轮parttiion比较后,再把轴值交换回轴值在排序后该在的位置
int small = start - 1; // 保证慢指针small从0开始
for (index = start; index < end; ++index) { // 只交换比较start和end-1之间的数
if (nums[index] < nums[end]) { // 满足快指针的值小于轴值的条件时
++small; // 因为上次交换完,small指向的是上次交换完的结果,比轴值要小,把慢指针small往后移动一个,本次交换要把快指针index指向的新小元素挪到前面,如果small等于index就不用交换,如果small不等于index,在small和index之间的元素必定要比轴值大,所以可以实现,把小的元素放在前面,把大的元素放在后边,如果听到这里还不清楚,建议自己画图,实际走一遍。
if (small != index) { // 快慢指针相同时,不用交换
swap(nums, small, index);
}
}
}
++small; // 因为之前开始时减了1,进行初始化,所以最后轴值该待的位置应该是small再加上1
swap(nums, small, end); // 把轴值换到一次parttiion后正确的位置,这是轴值前面全是比它小的小的,轴值后面全是比它大的
return small;
}
void quicksort(vector<int>& nums, int start, int end) {
if (start == end) // 相等的时候退出,从下往上合并
return;
int index = partition(nums, start, end); // 分割
if (index > start) { // 边缘条件限制,必须加,否则会导致访问数组以外的地址,溢出
quicksort(nums, start, index - 1);
}
if (index < end) { // 同上
quicksort(nums, index + 1, end);
}
}
int main() {
vector<int> numbers{3,2,1,5,6,4};
quicksort(numbers, 0, numbers.size() - 1);
for (int i = 0; i < numbers.size(); i++) {
cout << numbers[i] << endl;
}
system("pause");
return 0;
}边栏推荐
猜你喜欢

这种动态规划你见过吗——状态机动态规划之股票问题(中)

软件设计师考前20问,注意啦!!
![[jzof] 14 cut rope](/img/36/6f58b443a549ad245c1c4cfe5d13af.png)
[jzof] 14 cut rope

In hot weather, the line of defense for safe production was strengthened, and Guangzhou Haizhu District carried out emergency drills for gas stations

医药行业数字化建设,箭在弦上

Digital construction of pharmaceutical industry is on the verge

How to get more marks in the game under the new economic model of Plato farm

小黑重新站起来看leetcode:653. 两数之和 IV - 输入 BST

建筑建材行业B2B电子商务网站方案:赋能建材企业转型升级,实现降本提效

Redis interview questions must be known and learned
随机推荐
医药行业数字化建设,箭在弦上
Experiment 5: user and user group management
Take you to wechat applet development in 3 minutes
【JZOF】15二进制中1的位数
Redis设计规范
[openharmony] [rk2206] build openharmony compiler (2)
Plato farm - a farm meta universe game with Plato as the goal
Today, I want to talk about the data types of MySQL database
Array method of J S, loop
ASP. Net core 6 framework unveiling example demonstration [29]: building a file server
Introduction to thresholdfilter
Flink - checkpoint Failure reason: Not all required tasks are currently running
2022 uni app parsing token standard - use jsrsasign - climb the pit
选择供应商服务系统,是大健康产业企业迈向数字化转型的第一步
CloudCompare&PCL 匹配点采样一致性抑制
Judge whether the string is palindrome
网易笔试之不要二——欧式距离的典型应用
Database advanced learning notes -- storage functions
arthas使用教程
小黑重新站起来看leetcode:653. 两数之和 IV - 输入 BST