【算法 - 基础】归并排序
思想
归并排序主要采取分治的思想,在学习语法的过程中,我们会遇到这样一个问题:如何将两个有序数组合并为一个有序数组,归并排序就类似的采取了这样的操作。
这里以 2-路归并 为例:
- 想要排一个序列,可以将这个序列从中间分为左右两个序列。
- 当左右两个序列分别被排列成一个有序序列后,再合并为一个有序序列
- 而想要排列左右两个有序序列,则又可以将这两个序列依次分为两个序列,再进行排序后再合并
- 不断的重复操作后,可以将排序转化为如何按序合并的问题。
实现(C/C++)
归并排序模板
void Msort(int arr[],int left,int right){
if(left>=right) return;
//折中拆分
int mid=(left+right)/2; //或写成 mid = left+right>>1
Msort(arr,left,mid); //分左边
Msort(arr,mid+1,right); //分右边
//有序合并
int k=left,i=left,j=mid+1; //k辅助处理数据 i相当于左指针 j相当于右指针
while(i<=mid&&j<=right){
//从小到大排序
if(arr[i]<arr[j]) temp[k++]=arr[i++];
else temp[k++]=arr[j++];
}
//左右两边如果不一样长的话,则需要补位
while(i<=mid) temp[k++]=arr[i++]; //补左边
while(j<=right) temp[k++]=arr[j++]; //补右边
//排好后,将临时存储的数据还给原序列
for(i=left;i<k;i++){
arr[i]=temp[i];
}
}
时间复杂度与空间复杂度
时间复杂度
最好 = 最坏 = 平均 = O( nlogn )
空间复杂度
最好 = 最坏 = 平均 = O(n)
练习题 and 题解(不定期更新)
做题少,暂时还没遇到。