I. 归并排序
归并排序思想
- 将数组一分为二(折半);
- 分别将两部分数组进行排序;
- 将排序好的两部分数组进行合并成新的有序数组。
动态图演示
算法实现
利用分治算法,自顶向下的进行递归排序。动态图演示则为自下往上的排序演示。
public static void main(String[] args) {
int[] array = {
53, 34, 32, 56, 62, 121, 55, 41};
sort(array, 0, array.length - 1);
ArrayUtils.printArray(array);
}
private static void sort(int[] array, int start, int end) {
// 递归结束
if (start >= end) {
return;
}
int mid = (end + start) / 2;
sort(array, start, mid); // 左半排序
sort(array, mid + 1, end); // 右半排序
merge(array, start, mid + 1, end); // 归并
}
/**
* 两个有序的数组(start->mid - 1, mid->end)原地归并
* @param array 数组
* @param start 开始
* @param mid 中间
* @param end 结束
*/
public static void merge(int[] array, int start, int mid, int end) {
int[] copyArray = new int[end - start + 1];
for (int i = 0; i < copyArray.length; i++) {
copyArray[i] = array[i + start];
}
// 定义两个数组的指针,向后遍历比较
int leftIndex = start, rightIndex = mid;
for (int i = start; i <= end; i++) {
if (leftIndex >= mid) {
// 如果左边搞完
array[i] = copyArray[rightIndex - start];
rightIndex++;
} else if (rightIndex > end) {
// 如果右边边搞完
array[i] = copyArray[leftIndex - start];
leftIndex++;
} else if (copyArray[leftIndex - start] <= copyArray[rightIndex - start]) {
// 如果左边比右边小
array[i] = copyArray[leftIndex - start];
leftIndex++;
} else if (copyArray[leftIndex - start] > copyArray[rightIndex - start]) {
// 如果右边比左边小
array[i] = copyArray[rightIndex - start];
rightIndex++;
}
}
}
算法评价
排序方法 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
归并排序 | O(nlog2n) O ( n l o g 2 |