合并排序的原理不复杂,但之前没有用代码实现过。这次用Java写了下,感觉不难也不简单。比一般的递归更复杂点,如果没有一定的编程经验会很难。我这里写了个类(PointPair)来记录排序段。这样的话,就存在内存开销了,但合并算法就是用空间换时间吧。
关键是要理解这一句:
return merge(sort(new PointPair(pair.start, split)), sort(new PointPair(split, pair.end)));
package com.example.demo;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
Arrays.stream(MergeSort.sort(new int[]{9, 9, 9, 0, 0, 0, 4, 3, 2, 2, 1, 8})).forEach(i -> {
System.out.print(i + ",");
});
}
static int[] sort(int[] input) {
return new MergeSorter(input).getArr();
}
}
class MergeSorter {
private int[] arr;
public MergeSorter(int[] arr) {
this.arr = arr;
sort(new PointPair(0, arr.length));
}
private PointPair sort(PointPair pair) {
if (pair != null) {
if (pair.end - pair.start > 1) {
int split = pair.getSplit();
merge(sort(new PointPair(pair.start, split)), sort(new PointPair(split, pair.end)));
return pair;
}
return pair;
}
return null;
}
private void merge(PointPair pair, PointPair pair1) {
int[] copy = Arrays.copyOfRange(this.arr, pair.start, pair.end);
int start = pair.start;
int start1 = pair1.start;
int sorted = start;
start = 0;
while (start < copy.length && start1 < pair1.end) {
if (copy[start] > arr[start1]) {
arr[sorted] = arr[start1];
start1++;
} else {
arr[sorted] = copy[start];
start++;
}
sorted++;
}
while (start < copy.length) {
arr[sorted++] = copy[start++];
}
}
public int[] getArr() {
return arr;
}
class PointPair {
private int start;
private int end;
public PointPair(int start, int end) {
this.start = start;
this.end = end;
}
public int getSplit() {
return (start + end) / 2 + (start + end) % 2;
}
}
}