归并类排序是首先将原始无序序列划分成两个子序列,然后分别对每个子序列递归地进行排序,最后再将有序子序列合并。
归并排序是一种基于分治法的排序。
归并排序是简单地进行“分”,重点却在“合”的过程,即对两个有序子序列进行归并的过程:每次比较子序列头,取出较小的进入结果序列;其后继续比较两个子序列头,取出较小的进入结果序列,重复上述过程,直到其中一个子序列为空,剩余子序列中的元素就可以直接进入结果序列。
1. 归并排序
二路归并排序是首先将初始序列的 n 个记录看成是 n 个有序的子序列,每个子序列的长度为1.然后两两归并,得到 个长度为 2 ( n 为奇数时,最后一个序列的长度为 1)的有序子序列。在此基础上,再对长度为 2 的有序子序列进行两两归并,得到若千个长度为 4 的有序子序列。以此类推,直到得到一个长度为 n 的有序序列为止。
(图片来源:http://www.cnblogs.com/jingmoxukong/p/4308823.html)
1.1 代码实现
package com.zth.sort;
import java.util.Arrays;
/**
* @author 时光·漫步
* 二路归并排序
*/
public class MergeSort {
public static void main(String[] args){
Integer[] array = {3,2,5,8,4,7,6,9};
mergeSort(array);
System.out.println(Arrays.toString(array));
}
/**
* 排序算法驱动程序
*/
public static <AnyType extends Comparable<? super AnyType>>
void mergeSort(AnyType[] array){
// 临时辅助空间
AnyType[] tmpArray = (AnyType[])new Comparable[array.length];
mergeSort(array,tmpArray,0,array.length-1);
}
/**
* 用于递归调用的内部方法
* @param left 子序列的起始索引
* @param right 子序列的终止索引
*/
private static <AnyType extends Comparable<? super AnyType>>
void mergeSort(AnyType[] array,AnyType[] tmpArray,int left,int right){
if(left < right){
int center = (left + right)/2;
mergeSort(array,tmpArray,left,center);
mergeSort(array,tmpArray,center+1,right);
merge(array,tmpArray,left,center+1,right);
}
}
/**
*合并相邻两个有序子序列
* @param leftpos 第一个子序列的起始索引
* @param rightpos 第二个子序列的起始索引
* @param rightEnd 第二个子序列的终止索引
*/
private static <AnyType extends Comparable<? super AnyType>>
void merge(AnyType[] array,AnyType[] tmpArray,int leftpos,int rightpos,int rightEnd){
int leftEnd = rightpos -1;
int tmpPos = leftpos;
int numElements = rightEnd - leftpos+1;
// 两个子序列都不为空时
while (leftpos <= leftEnd && rightpos <= rightEnd){
if (array[leftpos].compareTo(array[rightpos]) <= 0 ){
tmpArray[tmpPos++] = array[leftpos++];
}else {
tmpArray[tmpPos++] = array[rightpos++];
}
}
// copy rest of the first subarray
while (leftpos <= leftEnd){
tmpArray[tmpPos++] = array[leftpos++];
}
// copy rest of the second subarray
while (rightpos <= rightEnd){
tmpArray[tmpPos++] = array[rightpos++];
}
// copy tmpArray back
for (int i = 0; i < numElements; i++,rightEnd--) {
array[rightEnd] = tmpArray[rightEnd];
}
}
}
1.2 性能分析
时间复杂度 | 空间复杂度 | 稳定性 | ||
平均情况 | 最坏情况 | 最好情况 | ||
O( N log N) | O( N log N) | O( N log N) | o(N) | 稳定 |