归并排序
基本思想:分治算法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序(二路归并就是指将两个有序表合并成一个有序表)
归并排序重要分以下三个部分:
1. 把要排序的区间平均切分成两个部分
2. 分治算法,对左右两个小区间进行同样方式的排序,直到size == 1(有序) && size == 0(没有数)
3. 合并左右两个有序区间到一个有序区间(需要利用额外空间)
//合并两个区间为一个区间
void merge(int[] array, int low, int mid, int high, int[] extra){
//int[] extra = new int[high - low]
int i = low; //遍历 [ low,mid )
int j = mid; //遍历 [ mid,high )
int x = 0; //遍历extra
while(i < mid && j < high){
if(array[i] < array[j]){
extra[x++] = array[i++];
}
if(array[i] > array[j]){
extra[x++] = array[j++];
}
while(i < mid){
extra[x++] = array[i++];
}
while(j < high){
extra[x++] = array[j++];
}
}
for(int k = low; k < high; k ++){
array[k] = extra[k - low];
}
}
实现归并排序算法:
//归并排序算法
void mergeSortInner(int[] array, int low, int high, int[] extra){
//1.判断终止条件(没有数||只有一个数)
if(low >= high || low == high - 1){
return;
}
//2.划分成两个有序区间
int mid = low + (low + high) / 2;
//分治算法处理两个小区间
mergeSortInner(array, low, mid, extra);
mergeSortInner(array, mid, high, extra);
//3.合并两个区间为一个区间
merge(array, low, mid, high, extra);
}
归并排序特性总结:
- 归并排序采用分治算法
- 归并排序的思考更多的是解决在磁盘中的外排序问题
- 时间复杂度:最好、最坏、平均都是O(n*log(n))
- 空间复杂度:O(n)
- 稳定性:稳定