6.归并排序
6.1实现思路
上图中的最后一次合并
,要将 [4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤:
6.2具体实现
public class MergeSort {
public static void main(String[] args) {
int[] array = {3, 6, 1, 6, 7, 8, 2, 8, 4};
mergeSort(array, 0, array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void mergeSort(int[] array, int low, int high) {
//递归结束的条件
if (low < high) {
int middle = (low + high) / 2;
//排左边
mergeSort(array, low, middle);
//排右边
mergeSort(array, middle + 1, high);
//归并
merge(array, 0, middle, high);
}
}
/**归并
* @param array 原始数组
* @param low 起始数组下标
* @param mid 中间数组下标(low+high)/2
* @param high 最后一位数组的下标
*/
public static void merge(int[] array, int low, int mid, int high) {
//用于存储归并后的临时数组
int[] temp = new int[high - low + 1];
//记录第一个数组中需要遍历的下标
int i = low;
//记录第二个数组中需要遍历的下标
int j = mid + 1;
//记录temp中的下标
int t = 0;
//遍历两个数组取出小的数字,放入temp
while (i <= mid && j <= high) {
if (array[i] < array[j]) {
temp[t] = array[i];
i++;
} else {
temp[t] = array[j];
j++;
}
t++;
}
//处理多余的数据
while (j <= high) {
temp[t] = array[j];
j++;
t++;
}
while (i <= mid) {
temp[t] = array[i];
i++;
t++;
}
//把临时数组中的数据重新存入原数组
for (int k = 0; k < temp.length; k++) {
array[k + low] = temp[k];
}
}
}
[1, 2, 3, 4, 6, 6, 7, 8, 8]
6.3测试归并排序算法的速度
public class MergeSort {
public static void main(String[] args) {
// int[] array = {3, 6, 1, 6, 7, 8, 2, 8, 4};
// mergeSort(array, 0, array.length - 1);
// System.out.println(Arrays.toString(array));
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int) (Math.random() * 800000);
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format1 = simpleDateFormat1.format(date1);
System.out.println("排序前的时间是:" + format1);
mergeSort(arr, 0, arr.length - 1);
Date date2 = new Date();
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format2 = simpleDateFormat2.format(date2);
System.out.println("排序后的时间是:" + format2);
}
public static void mergeSort(int[] array, int low, int high) {
//递归结束的条件
if (low < high) {
int middle = (low + high) / 2;
//排左边
mergeSort(array, low, middle);
//排右边
mergeSort(array, middle + 1, high);
//归并
merge(array, 0, middle, high);
}
}
/**
* 归并
*
* @param array 原始数组
* @param low 起始数组下标
* @param mid 中间数组下标(low+high)/2
* @param high 最后一位数组的下标
*/
public static void merge(int[] array, int low, int mid, int high) {
//用于存储归并后的临时数组
int[] temp = new int[high - low + 1];
//记录第一个数组中需要遍历的下标
int i = low;
//记录第二个数组中需要遍历的下标
int j = mid + 1;
//记录temp中的下标
int t = 0;
//遍历两个数组取出小的数字,放入temp
while (i <= mid && j <= high) {
if (array[i] < array[j]) {
temp[t] = array[i];
i++;
} else {
temp[t] = array[j];
j++;
}
t++;
}
//处理多余的数据
while (j <= high) {
temp[t] = array[j];
j++;
t++;
}
while (i <= mid) {
temp[t] = array[i];
i++;
t++;
}
//把临时数组中的数据重新存入原数组
for (int k = 0; k < temp.length; k++) {
array[k + low] = temp[k];
}
}
}
排序前的时间是:2021-01-09 17:12:14
排序后的时间是:2021-01-09 17:12:23