首页 > 编程语言 >快速排序算法的递归,迭代法实现(C++)

快速排序算法的递归,迭代法实现(C++)

时间:2023-01-14 11:04:29浏览次数:65  
标签:arr 递归 int top C++ ++ pivot 迭代法 stack



tags: DSA C++ Sort

思路

分治法

主要分成下面三个步骤:

  1. 选定基准值(默认是数组首元素), 这里称为pivot
  2. 找到基准值待放置的位置(排序之后的位置), 将大于基准值的元素放在基准值后面, 小于的放在前面
  3. 递归上述过程.

代码(递归)

下面这种方法是算法导论给出的, 先写子数组处理函数, 再给出递归过程. pivot取最右边元素:

int Partition(vector<int> &arr, int l, int r) {
/*i: the number of left side of x */
int x = arr[r], i = l - 1;
for (int j = l; j < r; ++j)
if (arr[j] <= x) swap(arr[++i], arr[j]);
swap(arr[++i], arr[r]);
return i; // 返回pivot插入的位置
}
// 递归实现快速排序算法
void QuickSort1(vector<int> &arr, int l, int r) {
if (l >= r) return;
int m = Partition(arr, l, r);
QuickSort1(arr, l, m - 1);
QuickSort1(arr, m + 1, r);
}

我改成了pivot取中间元素的情况:

int Partition(vector<int> &arr, int l, int r) {
/*i: the number of left side of x */
int mid = l + (r - l) / 2; // 选pivot
int pivot = arr[mid], i = l - 1;
for (int j = l; j <= r; ++j) {
if (j == mid) continue;
if (arr[j] <= pivot) swap(arr[++i], arr[j]);
}
swap(arr[++i], arr[mid]);
return i; // 返回pivot插入的位置
}
// 函数主体不变

以及经典的取首元素方法:

int Partition(vector<int> &arr, int l, int r) {
/*i: the number of left side of x */
int x = arr[l], i = l;
for (int j = l + 1; j <= r; ++j)
if (arr[j] <= x) swap(arr[++i], arr[j]);
swap(arr[i], arr[l]);
return i; // 返回pivot插入的位置
}

代码(迭代法)

用数组模拟栈, 放入左右边界(实际的递归变量), 参考​​1​​​,​​2​​.

/* arr --> Array to be sorted,
l --> Starting index,
r --> Ending index */
void QuickSort2(vector<int> &arr, int l, int r) {
int stack[r - l + 1];
// 栈顶指针(索引)
int top = -1;

stack[++top] = l;
stack[++top] = r;
// 栈空, 说明每一个子区间都被处理完了
while (top >= 0) {
r = stack[top--];
l = stack[top--];

int p = Partition(arr, l, r);
// pivot 左边元素入栈
if (p - 1 > l) {
stack[++top] = l;
stack[++top] = p - 1;
}
// pivot 右边元素入栈
if (p + 1 < r) {
stack[++top] = p + 1;
stack[++top] = r;
}
}
}

相当经典, 下面我用STL给出了一种比较简洁的写法:

void QuickSort(vector<int> &arr) {
int l{}, r = arr.size() - 1;
stack<pair<int, int>> st;
st.push(make_pair(l, r));
while (!st.empty()) {
tie(l, r) = st.top();
st.pop();
int p = Partition(arr, l, r);
if (p - 1 > l) st.push(make_pair(l, p - 1));
if (p + 1 < r) st.push(make_pair(p + 1, r));
}
}

ref


  1. ​Iterative Quick Sort - GeeksforGeeks​​; ↩︎
  2. ​​迭代的快速排序(Iterative Quick Sort)_K.Sun的博客-迭代版快速排序​​; ↩︎


标签:arr,递归,int,top,C++,++,pivot,迭代法,stack
From: https://blog.51cto.com/u_15366127/6007533

相关文章

  • C++ 算法进阶系列之从 Brute Force 到 KMP 字符串匹配算法的优化之路
    1.字符串匹配算法所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串。如在字符串ABCDEFG中查找是否存在EF字符串。可以把字符串ABCDE......
  • C++|开发工具
    前言学习c++就需要有合适的开发工具,本文将介绍如何安装开发工具。一、VisualStudio官网下载进入后,向下划,看到“了解VisualStudio系列”,选择使用于你的电脑操作系......
  • C++利用easyX实现一个简单图形化窗口
    在实现这个图形化窗口过程中遇到了一些琐碎的问题,不过还是解决了首先easyX下载地址https://easyx.cn/download下载之后安装到VS上或者自己想使用的软件上就行1#incl......
  • C++ STL容器的Value语义与Reference语义
    C++STL容器的Value语义与Reference语义1.Value语义vs.Reference语义1.1两种语义简述​ 通常情况下,所有容器都是建立元素的copy,返回的元素的copy。因此,容器内的元素与......
  • 洛谷P7792 KRIZA 题解 C++
    洛谷P7792KRIZA题解C++题目概述:题目传送门Sisyphus在一个圆形的房间里,房间内有n扇锁着的门,他有n把钥匙,其中第i把钥匙对应第$v_i$扇门,遇到不匹配的钥匙就放......
  • C++ 一种交换两个数的思路
    在Lua或者Python中可以使用多值赋值语句来交换两个数。例如:a,b=b,a。在C++中有没有类似的操作?先解析一下多值赋值的原理,a,b=b,a等价于t1,t2=b,aa,b......
  • 【假期刷些题-1】快速幂、递归幂次方、音速、快乐水
    因为很久没刷算法题了手有点生,所以刷些题记录下快速幂和取余运算//取模运算的性质(a*b)%p=[(a%p)*(b%p)]%p快速幂模板题https://www.luogu.com.cn/problem/P1226对......
  • 一笔画路径生成(c++版)
    一笔画路径生成(c++)练习图的遍历、回溯新建一个OnePen类;使用setNodeNum()方法设置节点数量;使用setNodeJoin()设置节点连线;执行drawLine()方法即可得出该图的一笔画......
  • C++中的size()、sizeof() 、strlen()、str.length()
    c/c++中获取字符串长度。有以下函数:size()、sizeof()、strlen()、str.length();一、数组或字符串的长度:sizeof()、strlen()1、sizeof():返回所占总空间的字节数2、str......
  • C++分别用顺序栈和链栈实现数制的转换相关代码
    //案例分析:将一个十进制数N转化为八进制数,在计算过程中,使得N模8得到八进制数的各个数依次进栈,//然后将八进制数依次输出,得到八进制数。#include<iostream>#include<cstdlib......