| 原地 | 稳定 | 最好 | 最坏 | 平均 |
---|
归并 | ✘ | ✔ | O(N logN) | O(N logN) | O(N logN) |
快排 | ✔ | ✘ | O(N logN) | O(N^2) | O(N logN) |
1 归并排序(Merge sort)
package sort;
import java.util.Arrays;
public class MergeSort {
public static void mergeSort(int[] nums, int numsLength) {
mergeSortInternally(nums, 0, numsLength - 1);
}
private static void mergeSortInternally(int[] nums, int numsStart, int numsEnd) {
if (numsStart >= numsEnd) {
return;
}
int mid = numsStart + (numsEnd - numsStart) / 2;
mergeSortInternally(nums, numsStart, mid);
mergeSortInternally(nums, mid + 1, numsEnd);
merge(nums, numsStart, numsEnd, mid);
}
private static void merge(int[] nums, int numsStart, int numsEnd, int mid) {
int preIndex = numsStart;
int backIndex = mid + 1;
int tmpIndex = 0;
int[] tmp = new int[numsEnd - numsStart + 1];
while (preIndex <= mid && backIndex <= numsEnd) {
if (nums[preIndex] <= nums[backIndex]) {
tmp[tmpIndex++] = nums[preIndex++];
} else {
tmp[tmpIndex++] = nums[backIndex++];
}
}
int remainStart = preIndex;
int remianEnd = mid;
if (backIndex <= numsEnd) {
remainStart = backIndex;
remianEnd = numsEnd;
}
while (remainStart <= remianEnd) {
tmp[tmpIndex++] = nums[remainStart++];
}
for (int j = 0; j < tmpIndex; j++) {
nums[numsStart + j] = tmp[j];
}
}
public static void main(String[] args) {
int[] nums = {9, 8, 7, 6, 5, 4, 3, 2, 1};
mergeSort(nums, nums.length);
System.out.println(Arrays.toString(nums));
}
}
2 快排
package sort;
import java.util.Arrays;
public class QuickSort {
public static void quickSort(int[] nums, int numsLength) {
quickSortInternally(nums, 0, numsLength - 1);
}
private static void quickSortInternally(int[] nums, int numsStart, int numsEnd) {
if (numsStart >= numsEnd) {
return;
}
int segIndex = partition(nums, numsStart, numsEnd);
quickSortInternally(nums, numsStart, segIndex - 1);
quickSortInternally(nums, segIndex + 1, numsEnd);
}
private static int partition(int[] nums, int numsStart, int numsEnd) {
int pivot = nums[numsEnd];
int i = numsStart;
for (int k = numsStart; k < numsEnd; ++k) {
if (nums[k] < pivot) {
if (i == k) {
++i;
}else{
int tmp = nums[i];
nums[i++] = nums[k];
nums[k] = tmp;
}
}
}
int tmp = nums[i];
nums[i] = nums[numsEnd];
nums[numsEnd] = tmp;
return i;
}
public static void main(String[] args) {
int[] nums = {3, 2, 1, 4, 9, 7, 6};
quickSort(nums, nums.length);
System.out.println(Arrays.toString(nums));
}
}
3 二分法 O(log N)
3.1 二分法注意
- 循环退出条件:
low <= high
- mid 的取值;
- low 和 high 的更新,
3.2 二分法的局限性
package sort;
public class Bsearch {
public static int bsearch(int[] nums, int len, int val) {
int low = 0;
int high = len - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (nums[mid] == val) {
return mid;
} else if (nums[mid] < val) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
public static int bsearch_2(int[] nums, int len, int val) {
return bsearchInternally(nums, 0, len - 1, val);
}
private static int bsearchInternally(int[] nums, int low, int high, int val) {
if (low > high) {
return -1;
}
int mid = low + (high - low) / 2;
if (nums[mid] == val) {
return mid;
} else if (nums[mid] < val) {
return bsearchInternally(nums, mid + 1, high, val);
} else {
return bsearchInternally(nums, low, mid - 1, val);
}
}
public static void main(String[] args) {
int[] nums = {6, 5, 4, 3, 2};
int index = bsearch(nums, nums.length, 4);
System.out.println(index);
}
}