归并排序
归并排序 Merge Sorted Array 左边排序,右边排序,左右两边合并 === 归并排序需要额外的空间用于合并(要倒腾出来,再倒腾回去)。
归并排序其本质是二叉树的后序遍历!即分治。
// 思想:左边排序、右边排序,然后再合并public class 归并排序{public static void mergeSort(int[] nums) {if (nums == null) {throw new RuntimeException("array is null");}mergeSortHelper(nums, 0, nums.length - 1);}// 思想:左边排序、右边排序,然后再合并static void mergeSortHelper(int[] nums, int start, int end) {if (start == end) {return;}// Divideint mid = start + (end - start) / 2;mergeSortHelper(nums, start, mid);mergeSortHelper(nums, mid + 1, end);// Conquermerge(nums, start, end, mid);}private static void merge(int[] nums, int start, int end, int mid){int[] helper = new int[end - start + 1];int p1 = start, p2 = mid + 1;int index = 0;while (p1 <= mid && p2 <= end) {if (nums[p1] < nums[p2]) {helper[index++] = nums[p1++];} else {helper[index++] = nums[p2++];}}if (p1 <= mid) {while (p1 <= mid) {helper[index++] = nums[p1++];}}if (p2 <= end) {while (p2 <= end) {helper[index++] = nums[p2++];}}for (int i = end; i >= start; i--) {nums[i] = helper[--index];}}public static void main(String[] args){int[] array = {1,5,7,2};mergeSort(array);for (int i : array){System.out.println(i);}}}
快速排序
快速排序 ==任取一个数target,将数组分成两部分,左边的<= target, 右边的 > target。然后左右两边再quick sort.复杂的在最坏的情况下是o(n2) 平均复杂度O(nlgn).
快速排序的本质是前序遍历。
// 思想:一个数组,随机找一个数字target,并将其放到正确的位置上(左边的数<=target,右边的数>target);然后左右两侧亦如此
public class 快速排序
{
public static void quickSort(int[] nums) {
if (nums == null) {
throw new RuntimeException("array is null");
}
quickSortHelper(nums, 0, nums.length - 1);
}
// position是寻找到的随机数字
static void quickSortHelper(int[] nums, int start, int end) {
// 第一步:将index = position的值归还到正确位置
Random random = new Random(end - start);
int position = random.nextInt() + start;
int target = nums[position];
int p1 = start, p2 = end;
while (p1 < p2) {
while (nums[p1] <= target && p1 < p2) {
p1++;
}
while (nums[p2] > target && p1 < p2) {
p2--;
}
if (p1 < p2) {
swap(nums, p1, p2);
}
}
quickSortHelper(nums, start, p1 - 1);
quickSortHelper(nums, p1 - 1, end);
}
private static void swap(int[] nums, int p1, int p2)
{
int temp = nums[p1];
nums[p1] = nums[p2];
nums[p2] = temp;
}
}
整体来说快拍优于归并排序,因为归并排序,需要额外的空间,然后将两个排序数组倒腾进去,然后再倒腾回去。。工程上常用快排
但是归并排序有个很好的地方,就是,其是稳定排序,而快拍不稳定。
