算法思想
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
算法步骤
1.分为两组,分别对两组排序,在对子数组排序的时候可能又要分而治之,当数组长度为1时不再分,
2.合并,两个子数组,盗图解释一下。。
这是分的过程,合并的过程是一个常见的二路归并算法,既我们常见的把两个有序数组合并为一个数字的另一种表述。
代码实现
import java.util.Arrays;
public class MergeSort {
//这是额外的内存,这就是归并排序消耗内存的地方,
static int[] temp;
static int n;
public static void main(String[] args) {
int []a={44,-20,1,3,2,4,5,4,8,6,-1,10};
n=a.length;
System.out.println();
mergeSort(a,0,n-1);
for (int i:a){
System.out.print(i+",");
}
}
static void mergeSort(int[]a,int left,int right){
if (left==right)return;
int mid=(left+right)/2;
//先分左右
mergeSort(a,left,mid);
mergeSort(a,mid+1,right);
//合并
merge(a,left,right,mid);
}
//对于已经排序好的两个子序列,二路归并
static void merge(int[] a,int left,int right,int mid){
temp= Arrays.copyOfRange(a,0,n);
//i是左边的下标,j是右边的下标,index是整个待merge序列的索引,将复制的左右两边放回数组
for (int i=left,j=mid+1,index=left;index<=right;index++){
//左边放完了放右边
if (i>mid){
a[index]=temp[j++];
}
//右边放完了放左边
else if (j>right)a[index]=temp[i++];
//放小的那个,左边大放右边,否则放左边,是稳定的
else if (temp[i]>temp[j])
a[index]=temp[j++];
else a[index]=temp[i++];
}
}
}
算法分析
每次归并复杂度为n,递归logn次,复杂度nlogn
空间复杂度就是复制的数组o(n),见注释,是稳定的