归并排序:
归并的含义是将两个或两个以上的有序表合并成一个新的有序表。归并排序有多路归并排序、两路归并排序 , 可用于内排序,也可以用于外排序。这里仅简单地对内排序的两路归并方法进行简要说明。
两路归并排序算法思路:
归并排序是分而治之思想的一种体现,使用了递归的实现方法。
每个递归过程涉及三个步骤
第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
第二, 治理: 对每个子序列分别调用归并排序, 进行递归操作
第三, 合并: 合并两个排好序的子序列,生成排序结果.
图示如下(请忽略图画的水平):
java代码实现:
理清算法思路后,实现的重点就在与将数组的已分别排好序的两部分合并为排序后的一部分,即merge方法实现。
其他就是将数组分成两部分,反复的合并,使用递归来实现。
package com.jdwa.utill;
import java.util.Arrays;
public class CzzTest {
public static void main(String[] args) {
int n = 1000000;
Integer[] source = new Integer[n];
for (int k = 0 ; k< n;k++){
Integer l = (int)(n*Math.random()); //随机生成0-100的数
source[k] = l;
}
System.out.println("排序前:"+ Arrays.toString(source));
mergeSort(source);
System.out.println("排序后:"+ Arrays.toString(source));
}
public static void mergeSort(Integer[] arr){
Long beg = System.currentTimeMillis();
mergeSortPer(arr,0,arr.length-1);
Long tm = System.currentTimeMillis() - beg;
System.out.println("执行时间:"+tm);
}
public static void mergeSortPer(Integer[] arr,int begin,int end){
if (begin>= end) return;
int mid=(begin+end)/2;
mergeSortPer(arr,begin,mid);
mergeSortPer(arr,mid+1,end);
merge(arr,begin,mid,end);
}
public static void merge(Integer[] arr,Integer begin,Integer mid,Integer end){
int i=begin,j=mid+1,k=0;
Integer[] tmp = new Integer[end-begin+1];
while (i <= mid && j <= end){
if (arr[i] < arr[j]){
tmp[k++] = arr[i++];
} else {
tmp[k++] = arr[j++];
}
}
while (i <= mid){
tmp[k++] = arr[i++];
}
while (j<=end){
tmp[k++] = arr[j++];
}
for (int p=begin;p<=end;p++){
arr[p] = tmp[p-begin];
}
}
}