【排序算法】-5.快速排序

前言:快排最早由图灵奖获得者Tony Hoare设计出来的,他在形式化理论以及ALGOL60编程语言中,都有卓越的发明中都有卓越的贡献。是上世纪最伟大的计算机科学家之一;快排是他的一个小发明,被列为20世纪十大算法(有关十大算法参见链接博客https://www.sohu.com/a/228987774_488171)之一。另外:快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影。

希尔排序相当于插入排序的升级,他们同属于插入排序类;

堆排序相当于选择排序的升级,他们同属于选择排序类;

快速排序属于最慢的冒泡排序的升级,同属于交换排序类;

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。

基本思想是:

  • 1.先从数列中取出一个数作为基准数。
  • 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  • 3.再对左右区间重复第二步,直到各区间只有一个数

 

第一趟排序之后:比基准数小的都在基准数左边,比基准数大的都在基准数右边:

之后的做法是

即递归:

递归执行的条件:i<j (保证i在j的左边)

#include<iostream>
#include<vector>

using namespace std;

void print(vector<int> a) {
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;
}

void quick_sort(vector<int> &arr,int start,int end) {
	//递归终止条件
	print(arr);

	if (start >= end) return;
	

	int i = start;
	int j = end;

	//基准数
	int temp = arr[start];
	if (i<j) {
		
		while (i<j)
		{
			 //从右往左找比基准数小的
			while (i<j && arr[j]>=temp) {
				j--;
			}
			//填坑
			if (i < j) {
				arr[i] = arr[j];
				i++;//填完数字 i右移
			}
			//从左向右找比基准数大的
			while (i<j && arr[i]<temp)
			{
				i++;
			}
			//填坑
			if (i < j) {
				arr[j] = arr[i];
				j--;
			}
		}
		//循环退出 i=j 基础数位置放在i = j的位置
		arr[i] = temp;//保证左边比基准数小,右边比基准数大
		//第一个基准数放在该放的位置

		//递归
		quick_sort(arr, start, i - 1);
		quick_sort(arr, i + 1, end);

	}
}


int main() {

	vector<int> arr{0,9,1,5,8,3,7,4,6,2};
	cout << "原数组:" << endl;
	print(arr);
	//快速排序


	quick_sort(arr, 0, arr.size() - 1);
	

	cout << "排序后:" << endl;
	print(arr);

	system("pause");

}

时间复杂度分析:时间性能取决于递归的深度:最优的情况是O(nlogn);最坏的情况是:O(n方)

//version.2
#include<iostream>
#include<vector>

using namespace std;

void print(vector<int> a) {
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;
}

int number(vector<int> &arr, int L, int R) {
	int i = L;
	int j = R;

	//基准数
	int temp = arr[i];



	while (i < j) {
		//从右往左找比基准数小的
		while (i < j && arr[j] >= temp) {
			j--;
		}
		arr[i] = arr[j];

		//从左往右找比基准数大的
		while (i < j && arr[i] < temp) {
			i++;
		}
		arr[j] = arr[i];
	}

	arr[i] = temp;
	return i;
}



void quick_sort(vector<int> &arr, int L, int R) {
	if (L >= R)return;
    
	int i = number(arr, L, R);

	quick_sort(arr, L, i - 1);
	quick_sort(arr, i + 1, R);
}


void main(){

	vector<int> arr = { 0,9,1,5,8,3,7,4,6,2 };
	print(arr);

	int l = 0;
	int r = arr.size()-1;

	quick_sort(arr, l, r);

	print(arr);
	system("pause");
}

 

快排非递归:

#include<iostream>
#include<vector>
#include<stack>

using namespace std;


int base_number(vector<int>&arr, int l, int r) {
	int i = l, j = r;
	int temp = arr[l];

	while (i < j) {
		while (i < j &&arr[j] >= temp) {
			j--;
		}
		arr[i] = arr[j];
		while (i < j &&arr[i] <= temp) {
			i++;
		}
		arr[j] = arr[i];
	}
	arr[i] = temp;

	return i;
}



void quicksort(vector<int>& arr, int l, int r) {
	stack<int> st;
	int k;
	if (l < r) {
		st.push(l);
		st.push(r);

		while (!st.empty()) {
			int j = st.top(); st.pop();
			int i = st.top(); st.pop();

			k = base_number(arr, i, j);//基准数

			if (i < k - 1) {
				st.push(i);
				st.push(k - 1);
			}

			if (j > k + 1) {
				st.push(k + 1);
				st.push(j);
			}
		}
	}
}


int main(){
	vector<int> arr = { 1,26,5,65,26,98,36,36,871,2,3,56 };

	quicksort(arr, 0, arr.size() - 1);
	
	for (int i = 0; i < arr.size() - 1; i++) {
		cout << arr[i] << " ";
	}


	system("pause");
	return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值