数据结构系列-归并排序
Posted 一个敲代码的阿信
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构系列-归并排序相关的知识,希望对你有一定的参考价值。
今日灵光乍现,将之前不懂的归并排序彻底搞清楚了,现在和大家分享。
一 实现过程
将数组对半分成两个数组,一直重复下去直到每个部分只剩下一个元素,将这些元素按照分解的过程重新归并,归并的过程中将元素排好序,直至将所有元素合并
二 分析
递推公式
mergeSort(s,e)=merge(mergeSort(s,r),mergeSort(r,e)) 其中r=(s+e)/2
终止条件
s>=e
三 复杂度
时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定非原地排序
四 注意点
刚开始的时候想要弄懂递推的每个步骤,在每个方法里打印变量,不打印还好,一打印反而更加迷糊了。
初次接触的时候,要观察数据特征,找出递推公式,发现终止条件,要把重点放在递推公式的推导和理解中。
五 代码
public static void mergeSort(int s, int e,int[] arr,int[] tmp){
if(s>=e)return ;
int middle = (s+e)/2;
//按照递推公式
mergeSort(s,middle,arr,tmp);
mergeSort(middle+1,e,arr,tmp);
merge(s,e,arr,tmp);
}
public static void merge(int s,int e,int[]arr, int[] tmp){
int start = s;
int end = e;
int leftMiddle = (s+e)/2;
int rightMiddle = leftMiddle+1;
int k = 0 ;
//这里用的while非常巧妙
while (start <= leftMiddle && rightMiddle <= end){
if (arr[start]<arr[rightMiddle])tmp[k++]=arr[start++];
else tmp[k++]=arr[rightMiddle++];
}
//上一个循环因为start <= leftMiddle 或者 rightMiddle <= end不符合条件而退出,所以需要补充下面两个循环
while (start<= leftMiddle){
tmp[k++] = arr[start++];
}
while (rightMiddle <= end){
tmp[k++] = arr[rightMiddle++];
}
//将tmp中排好序的元素重新赋值给arr
for (int i = 0;i<k;++i){
arr[s+i] = tmp[i]; //因为tmp和arr的存储维度不同,所以需要s+i
}
}
六 测试
七 复杂度分析
时间复杂度为O(nlogn),因为递归的深度为log2n,递归里的每个方法为O(n),所以总的复杂度为O(nlogn)
空间复杂度为O(n),因为归并排序需要额外的tmp的空间,而tmp的长度决定于arr的长度。
以上是关于数据结构系列-归并排序的主要内容,如果未能解决你的问题,请参考以下文章