数据结构(快速排序)

//快速排序

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

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

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

}

}

}

相关推荐
倒霉蛋小马5 分钟前
Java新特性:record关键字
java·开发语言
折哥的程序人生 · 物流技术专研21 分钟前
《Java 100 天进阶之路》第95篇:消息队列基础(RocketMQ/Kafka)(2026版)
java·面试·kafka·rocketmq·java-rocketmq·求职招聘
budingxiaomoli27 分钟前
Spring日志
java·开发语言
IT空门:门主31 分钟前
Spring 注入三剑客:@Resource、@Autowired、@RequiredArgsConstructor 到底该用哪个?
java·后端·spring
Sam_Deep_Thinking1 小时前
Spring Boot 的启动原理是什么?
java·spring boot·后端
南部余额1 小时前
Spring WebClient 从入门到精通
java·后端·spring
CodeStats1 小时前
从 CPU 指令到 JVM 进程:彻底讲透 Java 执行 main 方法时,类加载、主线程、栈帧入栈的完整底层逻辑
java·linux·开发语言
摇滚侠1 小时前
Spring 零基础入门到进阶 基于注解管理 Bean 38-43
xml·java·后端·spring·intellij-idea
happymaker06261 小时前
LeetCodeHot100——42.接雨水
算法