简介
归并排序是一种常见的排序方法,其核心思想是分而治之,利用两个有序的数组,依次选取出数组中最小的数,构建成新的数组,再进行迭代,最终实现对整个数组的排序。
实现
首先需要有一个函数对数组进行划分,完成递归的过程
// arr为需要排序的数组,L为开始排序的元素下标,R为结束排序的元素下标
public static void process(int[] arr, int L, int R) {
if (L = R) {
return;
}
int mid = L + ((R - L) >> 1); // 此处是计算中间值mid
process(arr, L, mid); // 此处进入递归,将原数组划分为左右两部分,直至L = R时跳出递归
process(arr, mid + 1, R);
merge(arr, L, mid, R); // 当跳出递归之后,进入归并排序的函数
}
将归并过程封装成一个函数,递归后产生的数组依次调用该函数
// arr为需要进行归并的数组,L为开始排序的元素下标,M为该数组的中间下标,R为结束排序的元素下标
public static void merge(int[] arr, int L, int M, int R) {
int helpArr = new int[R - L + 1]; // 建立一个辅助数组,临时存放排序好的元素,数组的大小为需要排序的范围的大小
int p1 = L; // p1指向左数组的最左侧
int p2 = M + 1; // p2指向右数组的最左侧
int i = 0 // i指向helpArr数组的当前元素
while (p1 <= M && p2 <= R) { // p1,p2指针都在各自数组范围内
helpArr[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2] ++;
// 判断左右两个数组的大小,取小的放到helpArr[i]处,同时i自增,赋值给helpArr[i]的数组左数组或者右数组自增 ,另一个保持不变
}
// 完成了上一个循环,必然有一个指针越界,将指针没越界的那个数组直接赋值进入新数组即可,因为递归时必然将每个子数组都排好了序
while (p1 <= M) {
helpArr[i++] = arr[p1++];
}
while (p2 <= R) {
helpArr[i++] = arr[p2++];
}
// 覆盖原数组
for (i = 0; i < helpArr.length; i ++) {
arr[i] = helpArr[i];
}
}
完整代码
import java.util.Arrays;
public class MergeSort {
public static void process(int[] arr, int L, int R) {
if (L == R) {
return;
}
int mid = L + ((R - L) >> 1);
process(arr, L, mid);
process(arr, mid + 1, R);
merge(arr, L, mid, R);
}
public static void merge(int[] arr, int L, int M, int R) {
int[] helpArr = new int[R - L + 1];
int p1 = L;
int p2 = M + 1;
int i = 0;
while (p1 <= M && p2 <= R) {
helpArr[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= M) {
helpArr[i++] = arr[p1++];
}
while (p2 <= R) {
helpArr[i++] = arr[p2++];
}
for (i = 0; i < helpArr.length; i ++) {
arr[L + i] = helpArr[i];
}
}
public static void main(String[] args) {
int[] arr = {5, 6, 7, 1, 2, 3};
process(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}