其他分享
首页 > 其他分享> > 快速排序

快速排序

作者:互联网

算法思路

  1. 每次都确定一个元素的最后位置,同时这个位置左边的数都是比它小,右边的数都是比它大
  2. 挖坑思路:
    • 两个指针,一个left,一个right
    • 每次大循环选一个元素flag(选最左边的,其实选什么都没关系),相当于挖了一个坑
    • 我们要从右边找到一个比flag小的元素,填上这个坑
    • 填上最初的坑,right的位置又多了一个新的坑,我们要从左边找出一个比flag大的元素,填上新的坑
    • 循环直到left==right,这个位置就是flag最后的位置
    • 再进行递归,分别flag左边的数组和右边的数组进行排序

书面概括

待排序的n个元素中任取一个元素(通常取第一个元素)作为枢轴(或支点),设其关键字为pivotkey。经过一趟排序后,把所有关键字小于pivotkey的元素交换到前面,把所有关键字大于pivotkey的元素交换到后面,结果将待排序记录分成两个子表,最后将枢轴放置在分界处的位置。然后,分别对左、右子表重复上述过程,直至每一子表只有一个元素时,排序完成。
其中,一趟快速排序的具体步骤如下。

  1. 选择待排序表中的第一个元素作为枢轴,把枢轴暂存在r[0]位置上。附设两个指针low和high,初始时分别指向表的下界和上界,(第一趟,low = 1;high = L.length)。
  2. 从表的最右侧位置依次向左搜索,找到第一个关键字小于枢轴关键字pivotkey的元素,将其移到low处。具体操作时:当low<high时,若high所指元素的关键字大于等于pivotkey,则向左移动指针high(执行操作:high--);否则将high所指元素与枢轴元素交换。
  3. 然后再从表的最左侧位置,依次向右搜索找到第一个关键字大于pivotkey的元素和枢轴元素交换。具体操作是:当low<high时,若low所指元素的关键字小于等于pivotkey,则向右移动指针low(执行操作:low++);否则将low所指元素与枢轴元素交换。
  4. 重复步骤2和3,直到low和high相等为止,此时low或high的位置即为枢轴在此趟排序中的最终位置,原表被分为两个子表。

在上述过程中,元素的交换都是与枢轴之间发生的,每次交换都要移动3次元素,可以先将枢轴元素暂存在r[0]位置上,排序过程中只需移动要与枢轴交换的元素,即只做r[low]和r[high]的单向移动,直至一趟排序结束后再将枢轴元素移至正确的位置。


考虑情况

排序过程会有三种情况

  1. 待排序元素大于有序序列中最大的元素;
  2. 待排序元素小于有序序列中的元素,但不小于有序序列中最小的元素;
  3. 待排序元素小于有序序列中最小的元素,但是因为监视哨的存在,2和3的情况归为一类。

算法效率

所以时间复杂度为O(n²)
下面的代码是我按照自己的思路进行编写的,算法效率没有达到应有的程度。

空间复杂度为O(1),监视哨。


算法特点


算法代码

#include <iostream>
#include <vector>
using namespace std;
void quickSort(vector<int>& v, int l, int r) {
	if (l >= r) return;
	int left = l, right = r;
	int flag = v[l];
	while (l < r) {
		while (l < r && v[r] >= flag) r--;
		v[l] = v[r];
		while (l < r && v[l] <= flag) l++;
		v[r] = v[l];
	}
	v[l] = flag;
	quickSort(v, left, l-1);
	quickSort(v, l+1, right);
}
int main() {
	vector<int> v = { 49,38,65,97,76,13,27,49 };
	quickSort(v, 0, v.size() - 1);
	for (auto a : v) cout << a << " ";
	cout << endl;

	return 0;
}

运行结果


标签:位置,元素,枢轴,flag,low,排序,快速
来源: https://www.cnblogs.com/wasi-991017/p/11970495.html