算法基础-排序-归并排序
归并排序的核心思想是分治。是将一个数组从中间分开,一直分开,直到子数组中只有一个元素,然后将这些子数组合并。
java实现代码如下:
1 package com.it.sort; 2 /** 3 4 *归并demo 5 */ 6 public class Demo 7 { 8 public static void main( String[] args ) 9 { 10 int array[] = {6,3,2,1,4,10,9,8,7,5}; 11 int b[]= new int[10]; 12 mergeSort(array,0,9,b); 13 for(int i = 0;i<array.length;i++){ 14 System.out.print(array[i]+" "); 15 } 16 } 17 public static int mergeSort(int[] a,int left,int right,int[] temp){ 18 if(left<right){ 19 //递归分治 20 int mid = left + (right-left)/2; 21 mergeSort(a,left,mid,temp); 22 mergeSort(a,mid+1,right,temp); 23 //合并将两个有序数组 24 mergeArray(a,left,mid,right,temp); 25 } 26 return a; 27 } 28 private static void mergeArray(int[] a, int left, int mid, int right,int[] temp) { 29 int i=left,j=mid+1,m=mid,n=right,k=0; 30 //二路归并,把较小的数先移入临时数组 31 while(i<=m&&j<=n){ 32 if(a[i]<=a[j]) 33 temp[k++] = a[i++]; 34 else 35 temp[k++] = a[j++]; 36 } 37 //把左边剩余的数移入数组 38 while(i<=m) 39 temp[k++] = a[i++]; 40 //把右边剩余的数移入数组 41 while(j<=n) 42 temp[k++] = a[j++]; 43 //从临时数组中拷贝到目标数组a 44 for(i=0;i<k;i++) 45 a[left+i] = temp[i]; 46 } 47 48 }
合并过程图解:
算法分析:
1.时间复杂度:
归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)。
2.空间复杂度:
算法处理过程中,需要一个大小为n的临时存储空间用以保存合并序列。
3.堆排,快排和归排比较:
若从空间复杂度来考虑:堆排序 快速排序,最后是归并排序。
若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。
若从平均情况下的排序速度考虑,应该选择快速排序。