这里讨论N(logN)的常见算法。
- Merge Sort
- Quick Sort
- Heap Sort
输入暂时都是整型数组
int[]
Merge sort
public class MergeSort {
private int[] mergeSort(int[] num, int start, int end) {
if (num == null || num.length == 0) {
return num;
}
if (start >= end) {
return new int[]{num[start]}; // divide until only one element left (return condition for recursion)
}
int middle = start + (end - start) / 2; // in case of: start = 1, end = Integer.MAX_VALUE, (start + end) will be out of bound
int[] left = mergeSort(num, start, middle);
int[] right = mergeSort(num, middle + 1, end);
return merge(left, right);
}
private int[] merge(int[] left, int[] right) {
int[] temp = new int[left.length + right.length];
int i = 0, j = 0, index = 0;
while (i < left.length && j < right.length) {
temp[index] = Math.min(left[i], right[j]);
if (left[i] < right[j]) {
i++;
} else {
j++;
}
index++;
}
while (i < left.length) {
temp[index++] = left[i++];
}
while (j < right.length) {
temp[index++] = right[j++];
}
return temp;
}
}
注意:
- 当divide到只剩下一个元素的时候(start 等于 end),返回包含此元素的一个新数组。
- 在取middle值的时候,不要使用
(start + end) / 2
,请使用模板:start + (end - start) / 2
。防止有超出Integer范围的情况。
Quick sort
public class QuickSort {
public void quickSort(int[] num) {
if (num == null || num.length == 0) {
return;
}
sort(num, 0, num.length - 1);
}
private void sort(int[] num, int start, int end) {
if (start >= end) {
return;
}
int pivot = num[end];
int i = start;
int j = end - 1;
while (i < j) {
while (num[i] <= pivot && i < j) {
i++;
}
while (num[j] > pivot && i < j) {
j--;
}
swap(num, i, j);
}
// check pivot position
if (num[i] > pivot) {
swap(num, i, end);
} else {
i++;
}
sort(num, start, i - 1);
sort(num, i + 1, end);
}
private void swap(int[] num, int i, int j) {
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
Quick sort 是 in-place,而merge sort是至少要花费O(N)的空间。
注意:
- recursion的终止条件为start跟end相遇。
- 左边是比pivot小,右边比pivot大
- 两个指针一个
++
,一个--