一、快速排序
快速排序相当于二叉树的前序遍历
思路:定义两个指针,定义一个基准值key,左边的都比key小,右边的都比基准值大。
时间复杂度:最好情况下O(NlogN), 最坏情况下O(N2)
先将中间部分排序好,在递归排序左边,递归排序右边。
代码部分:
public class Main{
public static void main(String[] args) {
int[] nums = {10, 5, 2, 8, 6, 9, 3};
System.out.println("排序前:" + Arrays.toString(nums));
quickSort(nums, 0, nums.length - 1);
System.out.println("排序后:" + Arrays.toString(nums));
}
public int findKthLargest(int[] nums, int k) {
quickSort(nums, 0, nums.length - 1);
return nums[nums.length - k];
}
public static void quickSort(int[] nums, int low, int high) {
//注意一:递归终止条件
if (low > high) {
return;
}
int left = low;
int right = high;
int key = nums[low];
while (left < right) {
//注意二:一定是right指针先移动
while (left < right && key <= nums[right]) {
right--;
}
while (left < right && key >= nums[left]) {
left++;
}
if (left < right) {
swap(nums, left, right);
}
}
//当left=right时,将此位置的数和基准值位置(left)交换---得到排序后,左边的数<基准值,右边的数>基准值
//注意三:一定返回right
swap(nums, low, right);
quickSort(nums, low, right - 1);
quickSort(nums, right + 1, high);
}
public static void swap(int[] nums, int low, int high) {
int temp = nums[low];
nums[low] = nums[high];
nums[high] = temp;
}
}
二、归并排序
归并排序相当于二叉树的后序遍历
先对左边排序,在对右边进行排序,最后合并代码
class Solution {
public int findKthLargest(int[] nums, int k) {
int[] temp = new int[nums.length];
sort(nums, 0, nums.length - 1, temp);
return nums[nums.length - k];
}
public static void sort(int[] nums, int low, int high, int[] temp) {
if (low == high) {
return; //单个元素不用排序
}
//1、将数组分成两版,这样写是为了防止溢出
int mid = low + (high - low) / 2;
//2、先对左半数组、右边数组分别递归排序
sort(nums, low, mid, temp);
sort(nums, mid + 1, high, temp);
//3、将两部分有序数组合并成 一个有序数组
merge(nums, low, mid, high, temp);
}
//将 nums[low,mid]和 nums[mid+1,high]这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int low, int mid, int high, int[] temp) {
//1、先把nums[low,high]复制到辅助数组temp中,以便合并后的结果能够直接存入nums
for (int i = low; i <= high; i++) {
temp[i] = nums[i];
}
//2、数组双指针技巧,合并两个有序数组
int i = low;
int j = mid + 1;
for (int p = low; p <= high; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并
nums[p] = temp[j++];
} else if (j == high + 1) {
// 右半边数组已全部被合并
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) { //对比大小
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}