一、算法描述
归并排序,是将一个数组,一步一步分割成每个表只含有一个元素的列表集,然后将子列表排序合并,生成大的有序列表。
通过归并子列表元素来合并子列表,完成排序。
二、步骤
- 将列表一分为二,两部分始末给出参数,作为索引
- 将其分割到最小,也就是分割后两部分都只有一个元素。
- 在分割过程中,递归的调用链就生成了,当分到最小时,将按链排序,生成越来越大的有序数组
- 在掉用到第一次分隔时,就完成了排序工作
三、代码
public class App
{
public static void main( String[] args )
{
//创建代排序数组
int[] a = new int[]{1,3,43,56,3,234,5,66,78,234,34,34,22,66,34,98,67};
//调用归并排序
MergeUtil.sortIntArry(a);
//打印排序好的数组
String result = "";
for(int i = 0 , len = a.length; i < len; i++){
result += a[i]+" ";
}
System.out.println(result);
}
}
public class MergeUtil {
public static void sortIntArry(int[] arr){
//创建一个临时数组存放被分开的元素
int[] tempArr = (int[])arr.clone();
//调用排序函数
msort(arr,tempArr,0,arr.length);
}
private static void msort(
int[] arr,int[] tempArr,int first,int last){
//如果拆分组有超过一个元素,则继续
if(first + 1 < last){
//将数组分为左右两部分
int midpt = (first + last)/2;
msort(arr,tempArr,first,midpt);
msort(arr,tempArr,midpt,last);
//子数组形成后,会倒叙依次执行下列操作,完成排序,并合
//如果数组已经是有序的,则直接复制用来优化归并排序对有序数组的排序速度。
if(arr[midpt - 1] < arr[midpt]){
return;
}
/*
* 由于是递归的,所以左右两数组,也就是[first,mid]和[mid,last],
* 是已经排序过的。这里要利用临时数组,把左右两个数组合并排序。
*/
int indexA = first;
int indexB = midpt;
int indexC = first;
//把得到左右数组中较小的值,并存临时数组
while(indexA < midpt && indexB < last){
if(arr[indexA] < arr[indexB]){
tempArr[indexC] = arr[indexA];
indexA++;
}else{
tempArr[indexC] = arr[indexB];
indexB++;
}
indexC++;
}
//把左右两数组中剩余的部分加到临时数组后
while (indexA < midpt){
tempArr[indexC] = arr[indexA];
indexA++;
indexC++;
}
while(indexB < last){
tempArr[indexC] = arr[indexB];
indexB++;
indexC++;
}
//拷贝排序好的临时数组到原数组
for(int i = first; i<last ; i++){
arr[i] = tempArr[i];
}
//最终会递归到第一次分组,完成上述合并操作,返回排序好的数组
}
}
}