快速排序

快速排序的优化、复杂度以及使用情况

#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

#if 0

快速排序是最慢的冒泡排序的升级 他们都属于交换排序类
即它是通过不断比较和移动交换来实现排序的,只不过它的实现
增大了记录的比较和移动的距离,将关键字较大的记录从前面直
接移动到后面,关键字较小的记录从后面直接移动到前面,从而
减少了总的比较次数和移动交换次数

快速排序的基本思想是:通过一趟排序记录分割成独立的俩部分,
其中一部分记录的关键字均比另一部分记录的关键字小,则可分
别对这俩部分记录继续进行排序,以达到整个序列有序的目的

本质是通过一次次确定中轴的位置,并根据此位置进行分区,
再确定分区中轴的位置一步步排序的
类似一次次通过二分法来确定顺序

时间复杂度:O[nlogn]
空间复杂度:O[logn]  主要是递归造成的栈空间的使用

适用情况:对于非常大的数组用起来会好 对于数组非常小则不如直接插入排序更好


#endif


int Partition(vector<int> & v,int low,int high)
{
	//改进方法:三值取中法 比较首中尾三个数据取合适值
	int mid = low + (high - low) / 2; //计算数组中间下标
	if (v[low] > v[high])
		swap(v[low], v[high]);   //交换首尾数据保证首端小
	if (v[mid]>v[high])
		swap(v[mid], v[high]);  //交换中尾数据保证中间小
	if (v[mid]>v[low])
		swap(v[mid], v[low]);   //交换首中数据保证下标为low的是中轴

	int middleValue = v[low]; //用表中第一个记录作为中轴

	while (low < high)   //从表俩侧向中轴交替扫描
	{
		while (low < high&&v[high] >= middleValue)  //从表尾端开始找一个比中轴小的数
			high--;  //尾端前移
		swap(v[low], v[high]);   //将中轴和在尾端开始比中轴小的数交换
		while (low < high&&v[low] <= middleValue)  //从表头端找一个比中轴大的数
			low++;
		swap(v[low], v[high]);   //将在尾端的中轴和头端小于中轴的数进行交换
	}
	return low;   //返回中轴所在位置 low high都可以 此时俩者重合
}

//优化后的方法 优化不必要的交换
int Partition1(vector<int> & v, int low, int high)
{
	int mid = low + (high - low) / 2; 
	if (v[low] > v[high])
		swap(v[low], v[high]);   
	if (v[mid]>v[high])
		swap(v[mid], v[high]);  
	if (v[mid]>v[low])
		swap(v[mid], v[low]);   

	int pivotkey = v[low]; 
	//将中轴备份 也可以通过设置哨兵的方式不将数组v[0]的
	//位置放入数据 将中轴备份给v[0]
	int i = pivotkey; 

	while (low < high)  
	{
		while (low < high&&v[high] >= pivotkey)  
			high--;  
		v[low] = v[high];  //采用赋值而不是交换
		while (low < high&&v[low] <= pivotkey) 
			low++;
		v[high] = v[low];  //采用赋值而不是交换
	}
	v[low] = i;  //将中轴赋值给当前位置
	return low;   //返回中轴所在位置 low high都可以 此时俩者重合
}


void QuickSort(vector<int>& v, int low, int high)
{
	if (low < high) //判断至少存在俩个元素
	{
		int mid = Partition(v, low, high); //或者用Partition1
		QuickSort(v, low, mid - 1); //对低子表递归排序
		QuickSort(v, mid + 1, high);//对高子表递归排序
	}
}

//递归的优化 实施尾递归的优化 采用迭代方法缩减栈深度
void QuickSort1(vector<int>& v, int low, int high)
{
	int pivot;  

	while (low < high) 
	{
		pivot = Partition(v, low, high); //或者用Partition1
		QuickSort1(v, low, pivot - 1); //对低子表递归排序
		low = pivot + 1;//尾递归
	}
}

int main(int argc,char *argv[])
{
	vector<int> v = { 50, 10, 90, 30, 70, 40, 80, 60, 20 };
	//哨兵模式
	vector<int> v1 = { 0, 50, 10, 90, 30, 70, 40, 80, 60, 20 };

	//参数含义是 数组 数组下标首位 数组下标末位
	QuickSort1(v, 0, v.size()-1); 
	for (auto c : v)
	{
		cout << c << endl;
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值