快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
  /****** 前序遍历位置 ******/
  // 通过交换元素构建分界点 p
  int p = partition(nums, lo, hi);
  /************************/

  sort(nums, lo, p - 1);
  sort(nums, p + 1, hi);
}
先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
  int mid = (lo + hi) / 2;
  // 排序 nums[lo..mid]
  sort(nums, lo, mid);
  // 排序 nums[mid+1..hi]
  sort(nums, mid + 1, hi);

  /****** 后序位置 ******/
  // 合并 nums[lo..mid] 和 nums[mid+1..hi]
  merge(nums, lo, mid, hi);
  /*********************/
}
先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。


一杯绿茶
199 声望17 粉丝

人在一起就是过节,心在一起就是团圆