版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_23013309/article/details/79728513
归并排序是建立在归并操作上的一种有效的排序算法。算法是基于分治思想,将大的问题分解为小的问题,当小问题解决后,大问题自然就解决了。但归并排序也有个缺点,它需要一个辅助空间,这个辅助空间与要排序的元素数量成正比。
public class MergeSort {
public static void sort (Comparable [] arr) {
sort(arr, 0, arr.length - 1);
}
// 对给定的数组进行排序
private static void sort (Comparable [] arr, int start, int end) {
// 递归结束的条件
if (start >= end) return;
int mid = (end + start) / 2;
sort(arr, start, mid);
sort(arr, mid + 1, end);
// 合并两个有序的数组
merge(arr, start, mid + 1, end);
}
// 合并两个有序的数组
private static void merge (Comparable [] arr, int start1, int start2, int end) {
// 先把要合并的数组做个备份放在临时数组temp中, 下面这样写是对的吗?
Comparable [] temp = new Comparable[end - start1 + 1];
for (int i=0; i < temp.length; i++) {
temp[i] = arr[start1 + i];
}
// 重新计算,原数组在temp数组中的起始位置
int m = 0, n = start2 - start1, mEnd = n - 1, i = start1;
// 开始对两个有序的数组进行合并
for (; i <= end && m <= mEnd && n < temp.length; i++) {
switch (compare(temp[m], temp[n])) {
case 0:
arr[i] = temp[m++];
break;
case 1:
arr[i] = temp[n++];
break;
case -1:
arr[i] = temp[m++];
break;
}
}
if (m <= mEnd && i <= end) {
// 这里刚开始写成了 m < mEnd 导致逻辑错误
while (m <= mEnd) {
arr[i++] = temp[m++];
}
}
if (n < temp.length && i <= end) {
while (n < temp.length) {
arr[i++] = temp[n++];
}
}
}
// 比较两个数的大小
private static int compare (Comparable c1, Comparable c2) {
int result = c1.compareTo(c2);
if (result > 0) return 1;
if (result < 0) return -1;
return 0;
}
private static void print(Comparable [] arr){
System.out.print("array is : ");
for (int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main (String [] args) {
Integer [] arr = {35, 25, 23, 1, 2, 3, 15, 14, 12, 13, 33, 43, 25, 3, 0, 100, 99, 88, 75};
System.out.println("排序前:");
print(arr);
sort(arr);
System.out.println("排序后:");
print(arr);
}
}