数据结构(快速排序)

//快速排序

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

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

//方法1 借助辅助空间

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

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

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

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

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

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

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

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

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

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

{

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

int tmp = arr[left];

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

while (left < right)

{

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

while (left<right && arr[right] > tmp)

right--;

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

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

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

if (left == right)

{

break;

}

arr[left] = arr[right];

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

while (left < right && arr[left] <= tmp)

left++;

if (left == right)

{

break;

}

arr[right] = arr[left];

}

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

arr[left] = tmp;//arr[right]=tmp;

return left; //return right

}

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

{

int tmp = arr[left];

while (left < right)

{

while (left<right && arr[right]>tmp)

right--;

if (left == right)

break;

arr[right] = arr[left];

}

arr[left] = 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);

}

}

}

相关推荐
薇茗1 小时前
【初阶数据结构】 升沉有序的平仄 排序 3
c语言·开发语言·数据结构·算法·排序算法·文件归并排序
字节高级特工1 小时前
C++11(一) 革新:右值引用与移动语义
java·开发语言·c++·人工智能·后端
孬甭_1 小时前
双向链表详解
c语言·数据结构·链表
薇茗1 小时前
【初阶数据结构】 升沉有序的平仄 排序 2
c语言·数据结构·算法·排序算法·快排精讲
郝学胜-神的一滴1 小时前
系统设计 012:从用户系统出发,吃透缓存、数据库与高并发设计
java·数据库·python·缓存·php·软件构建
AI科技星1 小时前
强哥德巴赫猜想(1+1)终极证明(2026 年5月 21 日)
开发语言·人工智能·算法·计算机视觉·量子计算
人道领域1 小时前
【LeetCode刷题日记】654.最大二叉树:递归算法详解
java·算法·leetcode
青云计划1 小时前
Synchronized 锁升级:从偏向锁到重量级锁的性能进化之路
java·后端
spencer_tseng1 小时前
HeapOOM && jvisualvm.exe
java·linux·jvisualvm.exe