数据结构(快速排序)

//快速排序

//每一趟将待排序以基准值为中心分成俩部分,左边部分的都小于基准值 右边部分的值,然后对其俩边部分再进行同样的处理即可

//怎么将数据以基准值中心划分分成俩部分

//方法1 借助辅助空间

//方法2 不借助辅助空间(挖空法)

//数据越快 反而效率越高

//数据越有序 反而效率低

//快速排序的优化:(怎么把数据打乱).

//1 快排刚刚启动时,如果待排序数据数据量较小,直接去调用直接插入 / 冒泡排序

//2.快排运行途中时,如果发现划分出来的小组里而的数量量小于一定的值,则直接调用直接插入

//3.三数取中法(取出范围内最左端值,最右端值,中间值这三个值,然后把不大不小的那个值放到最左端一会当基准值去用)

//4.随机数法(随机从里面取值,然后交换,执行多次这个操作即可)

//单次划分,用的方法是挖空法 (Partition)

int Partition(int arr\[\], int left, int right)

{

//1.先讲最左端的值,取出用tmp保存,防止一会被覆盖

int tmp = arrleft;

//2.进入while循环,条件是left没有和right相遇

while (left < right)

{

//3.先从右向左找,找一个比基准值小于或者等于的值,找到后扔到左边空位上

while (left<right && arrright > tmp)

right--;

//这个内部while循环结束,只会有两种可能性:

//可能1:随着right--,两个指针相遇了

//可能2:两个指针还没有相遇,但是确实找到了一个小于等于tmp的值,由此时的right指向

if (left == right)

{

break;

}

arrleft = arrright;

//4.再从左向右找,找一个比基准值大于的值,找到后扔到右边空位上

while (left < right && arrleft <= tmp)

left++;

if (left == right)

{

break;

}

arrright = arrleft;

}

//5.当while循环结束,表示left和right相遇了,此时就可以将tmp保存的基准值放回去了

arrleft = tmp;//arrright=tmp;

return left; //return right

}

/*int Partition(int arr\[\], int left, int right)

{

int tmp = arrleft;

while (left < right)

{

while (left<right && arrright>tmp)

right--;

if (left == right)

break;

arrright = arrleft;

}

arrleft = tmp;

return left*/;

}

//时间复杂度O(nlogn) 空间复杂度O(logn) 稳定性:不稳定

void Quick(int arr\[\], int left, int right)

{

//挖空法 (Partition)

//left = right 只有一个值

//left < right 不止一个值(>=2)

//left > right 一个值都没有

if (left >= right)

{

return;

}

int par = Partition(arr, left, right);

Quick(arr, left, par - 1);

Quick(arr, par + 1, right);

}

//void Quick(int arr\[\], int left, int right)

//{

// if (left >= right)

// {

// return;

// }

// int par = Partition(arr, left, right);

// Quick(arr, left, par - 1);

// Quick(arr, par + 1, right);

//}

//快速排序

void Quick_Sort(int arr\[\], int len) //递归的方式

{

Quick(arr, 0, len - 1);

}

//void Quick_Sort(int arr\[\].int len)

//{

// Quick(arr.0,len - 1);

//}

#include <stack>

//快速排序

void Quick_Sort_No_Recursion(int arr\[\], int len) //非递归的方式

{

std::stack<int> st;//因为是左右边界 所以入栈一次两个值 出栈也一次两个值

st.push(0);

st.push(len - 1);

while (!st.empty())

{

int right = st.top();

st.pop();

int left = st.top();

st.pop();

int par = Partition(arr, left, right);//left, par-1 par par+1, right

if (left < par - 1)//left, par-1

{

st.push(left);

st.push(par - 1);

}

if (par + 1 < right)//par+1, right

{

st.push(par + 1);

st.push(right);

}

}

}

相关推荐
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
vipxieliang3 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot