快速排序C++实现

快速排序的基本思想

快速排序是当前最为流行的排序算法之一,其平均时间复杂度为o(nlogn),基本思想是利用分治策略,每一趟排序中选取一个元素作为中轴元素,利用该元素,将待排序列分为独立的左右两部分(左半部分都比中轴元素小,右半部分都比中轴元素大);然后对两个子序列分别递归调用快排算法,直到子序列元素个数为1,整体序列有序。具体方法:

  1. 每一轮排序中,选择一个数作为中轴(默认取首元素,记下标为 [ i ] ),将其复制拿出,此位置即为一个待填的“坑”;
  2. 从后向前扫描序列,找到第一个小于中轴的元素(下标为 [ j ] ),将其放入前面的“坑”中,此时“坑”的位置转移至 [ j ] 下标处,扫描方式改变为从前向后(由 [ i +1 ] 开始)的寻找第一个大于中轴的元素;找到后将其填入 [ j ] 位置,“坑”位转移回到当前的 [ i ] 上,然后继续改变方向…直到 i=j 时,将中轴填入 [ i ] 位置,此时 i 之前的数都比中轴小, i 之后的数都比中轴大;
  3. 对中轴的左右两个区间重复第二步,直到各区间少于两个元素。

在这里插入图片描述

代码实现

#include <iostream>
#include <time.h>
#include <stack>
#include <algorithm>
using namespace std;

/*排序方法类*/
class MySort {
public:
	int n;
	int* A;
	//构造函数 ,便于挑选不同的排序方法
	MySort(int N) {
		this->n = N;
		A = new int[this->n];
		this->SetArray();
	}
	//随机初始化数组 
	void SetArray() {
		srand(time(0));
		for (int i = 0; i < n; i++) {
			A[i] = rand() % 100 + 1;
		}
	}
	//打印数组 
	void Print() {
		for (int i = 0; i < n; i++) {
			cout << A[i] << " ";
		}
		cout << endl;
	}


	//快速排序(递归法)
	void quick_sort(int left, int right) {          //待排数组首、尾位置
		if (left < right) {
			int i = left, j = right;
			int mid = A[left];                  //拿出首元素作为中轴x,此时A[left]为待填坑位
			while (i < j) {
				while (i < j && A[j] >= mid) // 从右向左找第一个小于x的数
					j--;
				if (i < j)                    //把A[j]填入A[i]中,此时坑位变为A[j],遍历方向变为从左向右
					A[i++] = A[j];
				while (i < j && A[i] < mid) // 从左向右找第一个大于等于x的数
					i++;
				if (i < j)                    //把A[i]填入A[j]中,改变方向同上
					A[j--] = A[i];
			}
			A[i] = mid;     //所有元素遍历后,i和j重合,中轴填入此位置
			quick_sort(left, i - 1); // 递归调用 
			quick_sort(i + 1, right);
		}
	}

	//快速排序(循环法)
	void quickSort( int left, int right) {
		stack<int> st;  //用于存放当前左右两端待排下标
		st.push(left);
		st.push(right);
		while (!st.empty()) {
			int r = st.top();
			st.pop();
			int l = st.top();
			st.pop();
			int i = l,j = r;
			int mid = A[(l + r) / 2];
			while (i <= j) {
				while (A[i] < mid) 	i++;
				while (A[j] > mid)  j--;
				if (i <= j) {
					swap(A[i], A[j]);
					i++;
					j--;
				}
			}
			if (l < j) {
				st.push(l);
				st.push(j);
			}
			if (i < r) {
				st.push(i);
				st.push(r);
			}
		}
	}
};

int main() {
	//初始化数组 
	int N;
	cout << "请输入数组长度:";
	cin >> N;
	MySort sort(N);   //构造排序方法类
	cout << endl;
	cout << "获得" << N << "位随机数组:";
	sort.Print();
	sort.quickSort(0, N - 1);
	cout << "快速排序后:";
	sort.Print();
	cout << endl;
	return 0;
}

算法验证:
在这里插入图片描述
快速排序的优化思路:

  1. 采用更合理的基准数(中轴),从而减少递归地深度。例如:从序列的不同位置取多个数,取其中位数作中轴。
  2. 结合插入排序,区间在10个元素以内采用插入排序,效率更高。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LiuZuqiang_3027

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值