数据结构(快速排序)

//快速排序

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

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

//方法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);

}

}

}

相关推荐
对空六课9 分钟前
指标口径生效时间的版本查询实现
大数据·服务器·前端·算法·数据分析
对空六课14 分钟前
RFM分层边界变化的回溯计算
大数据·服务器·前端·数据库·人工智能·算法·数据分析
一勺思维21 分钟前
我为什么把 Agent 的核心逻辑从 LangChain 里搬出来手写
算法
XIAEE22 分钟前
转生到儿童编程异世界:我用 Vue 和 Scratch 建了一座 DREAM 学院
java·spring
XIAEE29 分钟前
初次使用 Node + Koa + MongoDB 搭建服务器:从零到第一个 API
java·spring
m0_5873830034 分钟前
无人自助拼豆系统核心功能开发与部署落地全流程实战指南
java·经验分享·后端·struts·架构
碧海银沙音频科技研究院39 分钟前
基于炬芯ATS308X的LE aduio LC3编解码算法功能实现
算法
小蒋观天下41 分钟前
厂区人员徘徊游荡判别——基于时序轨迹速度的逗留行为分级算法落地
大数据·人工智能·深度学习·算法·机器学习·ai大模型
雷一言说43 分钟前
Spring AI 2.0:RAG 文档分块大小策略选择
java·spring
XIAEE43 分钟前
Java 世界历险记:从一行 System.out.println 到整个 Spring 宇宙
java·spring