归并排序利用分治思想:将一个大问题分为很多个小问题来处理
具体思想:将无序数组采用递归的思想一直等分,直到将无需数组分为每组只有一个元素,那么这时就自然有序了,分组之后需要进行合并,将分组之后的数组按照一定的顺序进行合并最后合并成的这个序列就是有序的
private static void mergeSortInternal(int[] arr, int low, int high) {
int mid = low + (high - low)/2;
if (low >= high){
return;
}
//分区
mergeSortInternal(arr,low,mid);
mergeSortInternal(arr,mid+1,high);
//合并
merge(arr,low,mid,high);
}
合并过程:
private static void merge(int[] arr, int p, int s, int q) {
int i = p;
int j = s + 1;
int[] temp = new int[q+1];
int k = 0;
//这里是按照顺序进行排序的过程
while (i <= s && j <= q){
if (arr[i] <= arr[j]){
temp[k++] = arr[i++];
}else {
temp[k++] = arr[j++];
}
}
while(i <= s){
temp[k++] = arr[i++];
}
//如果j至q区间还有元素,但i至s区间通过比较已经没有元素
while (j <= q){
temp[k++] = arr[j++];
}
//将临时数组的元素拷贝到原来数组
for (int t = 0;t < q-p+1;t++){
arr[p+t] = temp[t];
}
}
合并图:
在合并的过程中通过开辟临时空间的方法来帮我们保存当前已经排好序的数组,在合并结束后将临时空间的数据拷贝给原来的数组
分析:
稳定性:稳定
时间复杂度:O(nlogn)
空间复杂度:O(n)