12 | 排序(下):如何用快排思想在O(n)内查找第K大元素?

142 阅读2分钟

归并排序

归并排序原理(分治思想

  • 将数组从中间分为前后两部分

  • 分别对前后两部分进行排序,将排序后的两部分合并到一起

  • 需要依赖递归实现\

    • 分治是一种解决问题的思想
    • 递归是一种编程技巧

递推公式: merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r))  终止条件: p >= r 不用再继续分解
  • 性能分析

    • 稳定排序算法

      • 是否稳定取决于merge函数
      • merge保证前后顺序,则可以保证稳定
    • 时间复杂度

      • 递归问题可以转换成递推公司
      • 递归代码时间复杂度也可以写成递推公式
      • 无论最好,最坏和平均复杂度都是O(nlogn)
    • 空间复杂度

      • 在合并数组时需要借助额外的空间,所以不是原地排序算法
      • 空间复杂度=时间复杂度O(nlogn),如果考虑方法执行堆栈结构,空间复杂度是 O(n)
T(1) = C;   n=1时,只需要常量级的执行时间,所以表示为C。 T(n) = 2*T(n/2) + n; n>1

快速排序

快速排序的原理(分治思想)

  • 将数组根据一个数分为比其小和比其大的两个数组(swap)
  • 其余部分类似归并排序
  • 归并排序处理时由下之上的(小范围有序,大范围有序)
  • 快排处理是由上至下(1个元素放在合适的位置上,其余元素慢慢归位)

稳定算法:由于多次交换,快速排序注定不是稳定的排序算法

时间复杂度:普通O(nlogn),最坏O(n2)逆序的情况下(退化成了冒泡排序)

查询第K大的元素

利用分治思想,将第一个元素按照分层左右两个部分,再根据指针位置移动到下一个区间

时间复杂度:n+n/2+n/4+n/8+...+1 时间复杂度O(n)

总结

  • 归并排序和快速排序是两种稍微复杂的排序算法,它们用的都是分治的思想(递归实现)\

  • 归并排序空间复杂度O(n)\

  • 快排时间复杂度最坏是O(n2) 可以通过设置合理的pivot