归并排序(Merge Sort)
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
1 算法描述
- 把长度为n的输入序列分成两个长度为n/2的子序列;
- 对这两个子序列分别采用归并排序;
- 将两个排序好的子序列合并成一个最终的排序序列。
2 图解
可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程,递归深度为log2n。
3 代码实现
public class Sort {
public void mergeSort(int[]nums){
int length=nums.length;
int left=0,right=length-1;
int[]temp=new int[length];
sort(nums,left,right,temp);
}
private void sort(int[] nums, int left, int right, int[] temp) {
if(left<right){
int mid=(left+right)/2;
sort(nums,left,mid,temp);
sort(nums,mid+1,right,temp);
merge(nums,left,mid,right,temp);
}
}
private void merge(int[] nums, int left, int mid, int right, int[] temp) {
int i=left,j=mid+1,t=0;
while(i<=mid&&j<=right){
if(nums[i]<nums[j]){
temp[t++]=nums[i++];
}else {
temp[t++]=nums[j++];
}
}
while(i<=mid){
temp[t++]=nums[i++];
}
while (j<=right){
temp[t++]=nums[j++];
}
t=0;
for(int n=left;n<=right;n++){
nums[n]=temp[t++];
}
}
}
4 测试
import org.junit.Test;
public class TestSort {
private static int[] tem=new int[]{1,5,9,4,3,6,8,2,6,8};
private static Sort sort=new Sort();
@Test
public void testMergeSort(){
toArray();
sort.mergeSort(tem);
toArray();
}
public static void toArray(){
for(int i=0;i<tem.length;i++){
System.out.print(tem[i]+" ");
}
System.out.println();
}
}
结果如下: