思想
归并排序同快排一样,主要利用了分治策略,将一个大问题不断分解为可简单求解的小问题,分而治之,最后再逐步合并排序。同样的,快速傅里叶变换也运用了这种思想。
实现方法
首先通过递归思想将数组不断缩小,直至达到递归条件,之后通过Merge进行归并。
时间复杂度
归并排序的时间复杂度为:
O
(
n
l
o
g
n
)
O(nlog n)
O(nlogn)
归并排序的空间复杂度为:
O
(
n
)
O(n)
O(n)
提示:归并排序时间上非常快速,但是需要开辟额外的空间,且是一种稳定的排序方法:一次排序后数字的相对顺序不会改变。
程序实现
//java实现归并排序,利用递归思想,递归的出口在于数组不能再分
public class mergeSort{
public static void mergeSort(int[] nums,int begin,int end){
if(nums.length == 1){
return;
}
if(end <= begin){
return;
}
int mid = (begin + end)/2;
mergeSort(nums,begin,mid);
mergeSort(nums,mid+1,end);
Merge(nums,begin,mid,end);
}
public static void Merge(int[] nums, int begin,int mid,int end){
if(mid >= end){
return;}
int len = end-begin+1;
int[] temp = new int[len];
for(int i = begin; i <= end; i++){
temp[i-begin] = nums[i];
}
//排序temp[begin:mid],temp[mid+1:end]
int j = 0;
int k = mid+1-begin;
int i = begin;
while(j <= mid-begin && k <= end-begin){
if(temp[j] > temp[k]){
nums[i] = temp[k];
k = k+1;
}else{
nums[i] = temp[j];
j = j+1;
}
i=i+1;
}
if (j > mid-begin){
while(k <= end-begin){
nums[i] = temp[k];
i = i+1;
k = k+1;
}
}
if (k > end-begin){
while(j <= mid-begin){
nums[i] = temp[j];
i = i+1;
j = j+1;
}
}
}
public static void main(String[] args){
int[] nums = new int[]{4,1,3,5};
int begin = 0;
int end = 3;
mergeSort(nums,begin,end);
for(int i = 0; i <= 3;i++){
System.out.println(nums[i]);
}
}
}