归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
算法描述
- 把长度为n的输入序列分成长度为n/2的子序列;
- 对着两个子序列进行归并排序;
- 将两个排序好的序列合并成一个最终的排序序列;
算法复杂度
算法实现
代码实现
package thinkinjava;
import java.util.Random;
public class MergeSort {
static int num=0;
public static void main(String[] args) {
Random ran = new Random();
int count=1*10000;
int[] arr = new int[count];
for (int i = 0; i < arr.length; i++) {
arr[i] = ran.nextInt(count);
}
long l = System.currentTimeMillis();
sort(arr);
System.out.println(System.currentTimeMillis() - l);
}
//输出结果
public static void sort(int[] arr) {
sort(arr, 0, arr.length - 1);
}
public static void sort(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int mid = (left + right) / 2;
sort(arr, left, mid);
sort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
//合并,对数组进行排序
public static void merge(int[] arr, int left, int mid, int right) {
int[] arr1 = new int[arr.length];
int initialIndex=left;
int index = left;
int leftPointer = left;
int rightPointer = mid + 1;
// 设置两个指针,对两'数组'元素左起逐个比较,将较大的插入临时数组
while (leftPointer <= mid && rightPointer <= right) {
if (arr[leftPointer] >= arr[rightPointer]) {
arr1[index++] = arr[rightPointer++];
} else {
arr1[index++] = arr[leftPointer++];
}
}
// 将两'数组'剩余元素插入临时数组
while (leftPointer <= mid) {
arr1[index++] = arr[leftPointer++];
}
while (rightPointer <= right) {
arr1[index++] = arr[rightPointer++];
}
// 将临时数组中的元素拷贝到原数组中
while (initialIndex <= right) {
arr[initialIndex] = arr1[initialIndex];
initialIndex++;
}
}
}