当前位置:网站首页>QuickSort(快速排序)&&MergeSort(归并排序)的效率比较[搭配LeetCode例题]
QuickSort(快速排序)&&MergeSort(归并排序)的效率比较[搭配LeetCode例题]
2022-08-09 15:45:00 【老乐大魔王】
QuickSort(快速排序)&&MergeSort(归并排序)的效率比较
QuickSort代码
void quickSort(vector<int>& nums,int left,int right){
if(left>=right)
return;
int r=rand()%(right-left+1)+left;
int x=nums[r];
swap(nums[r],nums[right]);
int i=left-1;
for(int j=left;j<right;j++){
if(nums[j]<x)//由于随机数生成范围在[0,32768]之间,若生成数量大,则数重复率高,若此处改为nums[j]<=x,效率会变低很多很多
swap(nums[++i],nums[j]);
}
swap(nums[++i],nums[right]);
quickSort(nums,left,i-1);
quickSort(nums,i+1,right);
}
mergeSort代码
void mergeSort(vector<int>& nums,vector<int>& temp,int left,int right){
if(left>=right)
return;
int mid=(right+left)>>1
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
for(int i=left;i<=right;i++)
temp[i]=nums[i];
int i=left,j=mid+1;
for(int k=left;k<=right;k++){
if(i==mid+1)
nums[k]=temp[j++];
else if(j==right+1||temp[i]<=temp[j])
nums[k]=temp[i++];
else
nums[k]=nums[j++];
}
}
比较结果




总结
快速排序与归并算法都运用了分治思想,将问题分成子问题(可以简单求解的子问题)解决后再合并,归并注重与如何治(合并子问题),而快速排序着重于如何分(分解子问题)
快速排序相对归并排序来说不够稳定,不稳定的因素有以下三点:
- 与基准数比较之后产生的swap(相同值的相对位置的交换)会导致排序的不稳定
- 基准数归位之后的swap也会导致不稳定
- 基准数的随机选取也会导致不稳定
解决方案:用额外空间辅助空间实现稳定快速排序
def MySort(self , arr ):
if len(arr) <= 1:
return arr
left, right = [], []
for i in range(1,len(arr)):
if arr[i] < arr[0]:
left.append(arr[i])
else:
right.append(arr[i])
return self.MySort(left) + [arr[0]] + self.MySort(right)
大于等于(必须时大于等于)的放在右侧数组,小于的放在左侧数组,保证相同数字的相对位置,因为选用的是头部元素,相同的元素本来就在头部元素的右边,所以必须是大于等于。
保证了相同数字的相同数字的相对位置:return self.MySort(left) + [arr[0]] + self.MySort(right)
而效率取决于元素的排列是否随机,若接近排列接近有序时时间复杂度会达到O(n^2),我们应该根据不同的情况使用不同的算法,int,double,且数组长度在一定阀值内,则使用快排,如果在阀值外,则用归并。
衍生出来的子问题:
求数组中第k大的元素 215
用快速排序即可快速得到答案,只需增加一个比较即可,返回选中的分割数的下标等于(nums.size()-k)即可,因为是顺序排序,所以第k大的元素的下标为元素总数-k,若为要找的元素为第k小的元素则下标为k,逆序排序则反之。这里使用快速排序的时间复杂度其实O(n),因为每次只递归一个部分,该算法也叫快速选择,C++中的STL的nth_element()函数可以进行快速选择,此函数的效果为将数组第n小的元素放在数组的第n个位置,同时保证左侧元素不大于自身,右侧元素不小于自身。由快速选择引出的另一道题:
摆动排序 324
解法1:排序后分成两半,进行一小一大拉链合并,
解法2:
快速选择+Three way partition解决此题,时间复杂度为O(n),由于只需要找一个中位数,我们并不关心中位数的左右部分是否顺序,只需要满足左部分的元素小于中部分(中位数集合,因为中位数可能很多个),中部分的元素小于右部分即可。利用快速选择找出中位数,three way patition解决三部分问题当元素总数为奇数时mid=mid+1
求数组中的逆序对 剑指Offer-51
逆序对的意思按顺序从数组随机抽两个数,若后一个数比前一个大,则为逆序对。
如何使用归并排序的思想解决这道题呢?举个例子,数组A[2,8,10,11]和数组B[4,6,7,9],我们设置一个归并后的数组为C,当C数组为[2]时,数组B并无比2小的数,即2这个数字没有逆序对,当C数组为[2,4,6,7]时,数组A的二号元素8<数组B的三号元素9,此时到8入列为止之前B数组已经入列了三个元素分别为4、6、7,这三个元素都处于8的后面,且比8小,符合逆序对的标准
,即数组A的8能组成3个逆序对,之后C数组为[2,4,6,7,8,9]时,数组B已无元素可以归并,接下来依次将A数组的元素入列,入列的元素10与11能组成的逆序对数量均为B数组已经入列的元素数量4,逆序对的总数量为3+4+4=11
边栏推荐
猜你喜欢

3种特征分箱方法!

巧用Prometheus来扩展kubernetes调度器

网络——IPV4地址(三)

图像几何校正

The Chinese Academy of Sciences slaps Google in the face: ordinary computers catch up with quantum superiority, and can solve calculations that would have taken 10,000 years in a few hours...

【燃】是时候展现真正的实力了!一文看懂2022华为开发者大赛技术亮点

网络——介质访问控制

智慧灯杆网关智慧交通应用

2.1、基于并行上下文注意网络的场景文本图像超分辨率

A48基于NRF24L01的无线心率血氧体温检测
随机推荐
央企施工企业数字化转型的灵魂是什么
Became CTO, was killed by my boss in 6 months, I lost 10 million
第一篇博客
BETA:一个用于计算药物靶标预测的综合基准
Codeforces Round #808 (Div. 2)||Precipitation
四.数组传参
线性表之顺序表
如何让button中的内容分两行显示
2019强网杯高明的黑客
pgsql备份工具,哪个比较好?
A42 - 基于51单片机的洗衣机设计
Print the star chart "Recommended Collection"
领先实践|全球最大红酒App如何用设计冲刺创新vivino模式
Insert a number and sort "Suggested Favorites"
WeChat developer tools error, prompt did not find the entrance to the app. The json file
Volatile:JVM 我警告你,我的人你别乱动
DP 优化方法合集
@AllArgsConstructor 和 @NoArgsConstructor
成为CTO,6个月被老板干死,我损失了1000万
Qt学习第二天