归并排序:
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 归并排序是一种稳定的排序方法。 将已有序的子序列合并,得到完全有序的序列; 即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。 思路: 步骤1:把长度为n的输入序列分成两个长度为n/2的子序列; 步骤2:对这两个子序列分别采用归并排序; 步骤3:将两个排序好的子序列合并成一个最终的排序序列。
算法分析
- 最佳情况:T(n) = O(n)
- 最差情况:T(n) = O(nlogn)
- 平均情况:T(n) = O(nlogn)
代码如下:
public class MergeSort {
public static void main(String[] args) {
//定义一个大点的数组,测试归并排序需要多长时间
// 给8w个随机数排序
int arr[] = new int[8000000];
//随机生成数
for (int i = 0; i < arr.length; i++) {
//生成0~100w之间的随机数
arr[i] = (int) (Math.random() * 100);
}
/*System.out.println("排序前");
for (int i = 0; i < arr.length; i++) {
System.out.printf("%d%c", arr[i], (i + 1) % 8 == 0 ? '\n' : 32);
}*/
long startTime = Long.valueOf(String.valueOf(System.currentTimeMillis()));
mergeSort(arr,0, arr.length-1);
long endTime = Long.valueOf(String.valueOf(System.currentTimeMillis()));
/*System.out.println("排序后");
for (int i = 0; i < arr.length; i++) {
System.out.printf("%d%c",arr[i], (i+1) % 8 == 0 ? '\n' : 32 );
}*/
System.out.println("归并排序给"+arr.length+"个数据排序的时间(ms)为:" + (endTime - startTime)); // 8w 10ms, 800w 904ms
}
/**
* 实现归并
*/
private static void merge(int[] arr,int low,int mid,int high){
//定义临时数组
int tempArr[] = new int[high - low + 1];
int k = 0;
int i = low;
int j = mid+1;
while ( i <= mid && j <= high ){
if (arr[i] > arr[j]){//从小到大排序
tempArr[k++] = arr[j++];
}else {
tempArr[k++] = arr[i++];
}
}
//如果左边的序列遍历完了,但是右边还没遍历完成,就直接把右边序列中的元素复制到临时数组中
if ( j <= high){
for (int l = j; l <= high; l++) {
tempArr[k++] = arr[l];
}
}
//如果右边的序列遍历完了,但是左边还没遍历完成,就直接把左边序列中的元素复制到临时数组中
if (i <= mid){
for (int l = i; l <= mid; l++) {
tempArr[k++] = arr[l];
}
}
//将临时数组中的值复制给原来的数组
i = low;
for (int tempK = 0;(tempK <= k) && (i <= high) ; i++,tempK++) {
arr[i] = tempArr[tempK];
}
}
/**
* 实现归并排序,将一个长度为n序列拆解成n个序列长度为1的序列
* @param arr
* @param low
* @param high
*/
private static void mergeSort(int[] arr,int low,int high) {
//退出递归的条件
if (low < high){
int mid = ( low + high ) / 2;
//递归分解左边的子序列
mergeSort(arr,low,mid);
//递归分解右边的子序列
mergeSort(arr,mid+1,high);
//归并
merge(arr,low,mid,high);
}
}
}