算法思路
分而治之(divide - conquer);每个递归过程涉及三个步骤
第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作
第三, 合并: 合并两个排好序的子序列,生成排序结果.
java实现
public class SortUtil{
public static void mergeSort( int[] a ){
//创建一个临时数组用于保存排序后的值,在最后的merge方法中再把排序好的值赋给a数组
int[] temp = new int[ a.length ];
//调用重载方法
mergeSort( a, temp, 0, a.length - 1 );
}
public static void mergeSort( int[] a, int[] temp, int left, int right ){
//拆分数组,直到左指针大于等于右指针,说明已经不可再拆分了
if( left < right ){
int center = ( left + right ) / 2;
//递归拆分左子数组
mergeSort(a,temp,left,center);
//递归拆分右子数组
mergeSort(a,temp,center + 1,right);
//合并排序左子数组和右子数组
merge(a,temp,left,center + 1,right);
}
}
public static void merge( int[] a,int[] temp,int leftPos,int rightPos,int rightEnd){
//左子数组结束的下标指针
int leftEnd = rightPos - 1;
//临时数组开始下标指针,左子数组开始的位置
int tempPos = leftPos;
//一共合并多少个元素
int numElements = rightEnd - leftPos + 1;
//左子数组和右子数组分别从对应开始的位置比较,直到其中一个子数组元素全部比较完,退出循环
while( leftPos <= leftEnd && rightPos <= rightEnd)
//比较左右子数组当前位置的值大小,小的赋给临时数组保存排序好的值
if( a[ leftPos ] < a[ rightPos ] )
temp[ tempPos++ ] = a[ leftPos++ ];
else
temp[ tempPos++ ] = a[ rightPos++ ];
//经过上面的循环,肯定是有一个子数组已经比较完了,那么将另一个子数组还没比较的值直接赋给
//临时数组
while( leftPos <= leftEnd )
temp[ tempPos++ ] = a[ leftPos++ ];
while( rightPos <= rightEnd )
temp[ tempPos++ ] = a[ rightPos++ ];
//最后将临时数组保存的已排序好的值赋给原数组,rightEnd--表示从临时数组末端往前赋值
for(int i = 0; i < numElements; i++ ,rightEnd--)
a[ rightEnd ] = temp[ rightEnd ];
}
public static void main( string[] args ){
int[] a = new int[]{ 6,10,1,9,8,5,3,56};
mergeSort(a);
for (int i = 0; i < a.length; i++) {
System.out.println( a[i] );
}
}
}