归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,在使子序列段有序。若将两个有序表合并成一个有序表,称为2路归并。
- 时间复杂度:O(nlog2n)
- 空间复杂度:O(n)
- 稳定性:稳定
package 排序算法;
import java.util.Arrays;
import java.util.Random;
public class MergSort {
public static void main(String[] args) {
int arr[]=new int[20];
Random random=new Random();
for (int i=0;i<arr.length;i++){
arr[i]=random.nextInt(50);
}
mergSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
private static void mergSort(int[] arr, int l, int r) {
//优化:如果元素少 则直接排序
if(r-l<=10){
ShellSort.shellSort(arr,l,r);
return;
}
int mid=(l+r)/2;
mergSort(arr,l,mid);
mergSort(arr,mid+1,r);
//2.优化:如果左边的尾<右边的头 则没必要并
if(arr[mid]>arr[mid+1]){
merge(arr,l,mid,r);
}
}
private static void merge(int[] arr, int l, int mid, int r) {
int [] aux=new int [r-l+1];
for (int i=l;i<=r;i++){
aux[i-l]=arr[i];
}
int i=l;
int j=mid+1;
for (int k=l;k<=r;k++){
if(i>mid){
arr[k]=aux[j-l];
j++;
}else if(j>r){
arr[k]=aux[i-l];
i++;
}else if (aux[i-l]<aux[j-l]){
arr[k]=aux[i-l];
i++;
}else {
arr[k]=aux[j-l];
j++;
}
}
}
}
执行结果
[1, 3, 3, 5, 7, 10, 10, 18, 18, 21, 22, 26, 26, 27, 35, 35, 38, 43, 48, 49]
测试(完全随机情况下)
package 排序算法;
import java.util.Arrays;
import java.util.Random;
public class TestSort {
/*
数据分布情况
1.完全随机
2.大致有序
3.方差小
*/
public static int[] getTotalRandom(){
Random random=new Random();
int [] arr=new int[10000];
for (int i=0;i<arr.length;i++){
arr[i]=random.nextInt(10000);
}
return arr;
}
public static void main(String[] args) {
int [] arr1=getTotalRandom();
int [] arr2= Arrays.copyOf(arr1, arr1.length);
int [] arr3= Arrays.copyOf(arr1, arr1.length);
int [] arr4= Arrays.copyOf(arr1, arr1.length);
int [] arr5= Arrays.copyOf(arr1, arr1.length);
testSelectionSort(arr1);
testBubbleSort(arr2);
testInsertSort(arr3);
testShellSort(arr4);
testMergSort(arr5);
}
private static void testInsertSort(int[] arr3) {
long startTime=System.currentTimeMillis();
BubbleSort.bubbleSort(arr3);
long endTime=System.currentTimeMillis();
System.out.println("冒泡排序"+(endTime-startTime));
}
private static void testBubbleSort(int[] arr2) {
long startTime=System.currentTimeMillis();
insertionSort.lnsertionSortUpper(arr2);
long endTime=System.currentTimeMillis();
System.out.println("插入排序"+(endTime-startTime));
}
private static void testSelectionSort(int[] arr) {
long startTime=System.currentTimeMillis();
SelectionSort.selectionSort(arr);
long endTime=System.currentTimeMillis();
System.out.println("选择排序"+(endTime-startTime));
}
private static void testShellSort(int[] arr) {
long startTime=System.currentTimeMillis();
ShellSort.shellSort(arr);
long endTime=System.currentTimeMillis();
System.out.println("希尔排序"+(endTime-startTime));
}
private static void testMergSort(int[] arr) {
long startTime=System.currentTimeMillis();
MergSort.mergSort(arr,0,arr.length-1);
long endTime=System.currentTimeMillis();
System.out.println("归并排序"+(endTime-startTime));
}
}
执行结果
选择排序207
插入排序14
冒泡排序181
希尔排序12
归并排序29