归并排序
归并排序思想
简单来说归并排序的思想可以理解为分治思想。
如果左边的区间有序,并且右边的区间有序,则只需要执行合并两个有序数组。
完成代码的步骤
- 创建一个新数组,长度至少是 high - low
- while (两个数组都还有数字)
- 比较两边的选出来的数字,小的放到新数组中(尾插)
- 分别表示个区间的下标
- 再把某个还有数字的数组中的所有元素,直接尾插到新数组后边
实际操作
通过分组将此数组分裂成若干个数组进行排序最后进行合并
具体代码
public class MergeSort {
public static void mergeSort(long[] array) {
mergeSortInternal(array, 0, array.length);
}
// [low, high) 左闭右开
private static void mergeSortInternal(long[] array, int low, int high) {
int size = high - low;
if (size <= 1) {
return;
}
int mid = (low + high) / 2;
mergeSortInternal(array, low, mid);
mergeSortInternal(array, mid, high);
// [low, mid) 已经有序 并且 [mid, high) 也已经有序了
merge(array, low, mid, high);
}
// array[low, mid)
// array[mid, high)
private static void merge(long[] array, int low, int mid, int high) {
int leftSize = mid - low;
int rightSize = high - mid;
int size = leftSize + rightSize;
// 1. 创建一个新数组,长度至少是 high - low
long[] extraArray = new long[size]; // extra:额外的
// 2. while (两个数组都还有数字) {
// 3. 比较两边的选出来的数字,小的放到新数组中(尾插)
// 4. }
int leftIndex = low; // 左边区间的下标
int rightIndex = mid; // 右边区间的下标
int extraIndex = 0; // 额外数组的下标
while (leftIndex < mid && rightIndex < high) {
if (array[leftIndex] <= array[rightIndex]) {
extraArray[extraIndex] = array[leftIndex];
extraIndex++;
leftIndex++;
} else {
extraArray[extraIndex] = array[rightIndex];
extraIndex++;
rightIndex++;
}
}
// 5. 再把某个还有数字的数组中的所有元素,直接尾插到新数组后边
while (leftIndex < mid) {
extraArray[extraIndex] = array[leftIndex];
extraIndex++;
leftIndex++;
}
while (rightIndex < high) {
extraArray[extraIndex] = array[rightIndex];
extraIndex++;
rightIndex++;
}
// 6. 把数字从新数组复制回 array 中
// 从 extraArray 复制回 array 时
// extraIndex = 0 index = low + 0
// extraIndex = 1 index = low + 1
// index = extraIndex + low
for (int i = 0; i < size; i++) {
array[low + i] = extraArray[i];
}
}
public static void main(String[] args) {
long array[]={2,1,5,7,3,8,4,9,6,0};
System.out.println(Arrays.toString(array));
mergeSort(array);
System.out.println(Arrays.toString(array));
}
}