归并排序(Merging Sort):
- 归并排序就是将两个或者两个以上的有序表合并成一个有序表的过程。将两个有序表合成一个有序表的过程称为称为2路归并。归并排序是稳定排序。
- 思想:假设初始化序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2(往上取整)个长度为2或者1的有序子序列,再两两归并,……,如此重复,直到得到长度为n的有序序列。
- 图解:
- 代码实现(递归思想):
#include<iostream>
using namespace std;
void merging_insert(int *array, int *t_array, int low, int mid, int high){
int i=low,j=mid+1,t=low;
while(i<=mid&&j<=high){ //将array中记录由大到小插入到t_array
if(array[i]<array[j]) //找到左枝和右枝较小值,插入到t_array
t_array[t++] = array[i++]; //左枝较小进行插入
else
t_array[t++] = array[j++]; //右枝较小进行插入
}
//将左枝或者右枝剩余的值全部插入到t_array当中
while(i<=mid)
t_array[t++] = array[i++];
while(j<=high)
t_array[t++] = array[j++];
for(i=0; i<j; i++) //将和并好的值存在array中
array[i] = t_array[i];
}
void merging_sort(int *array, int *t_array, int low, int high){
if(low<high){
int mid = low+(high-low)/2; //计算分裂点
merging_sort(array, t_array, low, mid); //对左枝进行分裂
merging_sort(array, t_array, mid+1, high); //对右枝进行分裂
merging_insert(array, t_array, low, mid, high); //对左右枝进行合并排序
}
}
int main(){
int data[] = {49,38,65,97,76,13,27,16};
int temp[8] = {0}; //暂时存储数组,初始化为0
merging_sort(data, temp, 0, 7);
for(int i=0; i<8; i++){
cout<<temp[i]<<" ";
}
return 0;
}
Output:13 16 27 38 49 65 76 97
- 时间复杂度:
当有n个记录时,需要进行归并的次数为log2(n) (向上取整),而每趟归并最大的比较次数也小于等于n,故时间复杂度为O( n*log2(n) )
- 空间复杂度:
需要一个长度为n的数组的辅助存储,空间复杂度为O(n)