普林斯顿公开课 算法3-7:排序算法复杂度

算法复杂度用来表示在解决某个问题时,算法的性能表现。

复杂度上限,就是某个具体的已经实现的算法能够保证在一定时间内解决问题

复杂度下限,就是通过数学方法证明,所有的算法都必须花费一定的时间才能解决问题

最优化算法,就是可能达到的最小复杂度的算法,通常介于复杂度上限和下限之间

比如排序问题中:

  • 计算模型为决策树
  • 使用比较次数作为开销依据
  • 复杂度上限:使用归并排序可以达到N lgN复杂度
  • 复杂度下限:?
  • 最优化算法:?

决策树举例

有三个不同的元素a b c,通过比较的方式来得出排序结果。那么它的决策树为下图所示:

树的高度代表了最差情况下需要比较的次数。

树的宽度代表了可能的排列顺序。

证明

命题

任何基于比较的排序算法在最坏情况下至少要lg(N!) 到 N lgN 次比较。

证明

  1. 假设数组由N个不同的值组成,从a1到an
  2. 最坏情况由决策树的高度决定
  3. 二叉树最多可能的叶子节点数是2^h
  4. 因为数组有N!中不同的排序方式,所以至少有N!个叶子节点

结论

  • 计算模型为决策树
  • 使用比较次数作为开销依据
  • 复杂度上限:使用归并排序可以达到N lgN复杂度
  • 复杂度下限:N lgN
  • 最优化算法:归并排序

归并排序从比较次数来说是所有排序算法中最少的,但是从内存占用方面来讲并不是最优的。

因此要用理论作为指导,不要试图设计一种比N lgN复杂度还要小的排序算法(基于比较的排序算法)。

在实际应用中,可能有时候已经知道输入的数组有些特殊的性质,比如数组有一部分已经经过排序了,数组大致已经排序,数组中有许多重复值等。所以在实际应用中可以依据输入数据的特殊性质来选择合适的排序算法。比如对于已经大致排序的数组,可以使用插入排序实现复杂度为N的排序。

普林斯顿公开课 算法3-7:排序算法复杂度

时间: 2024-10-26 08:48:55

普林斯顿公开课 算法3-7:排序算法复杂度的相关文章

普林斯顿公开课 算法2-1:排序概述

目标 对所有类型的数据进行排序. 问题 排序函数如何知道比较的是哪种类型的数据呢? 回调函数 这时候就需要引入回调函数的概念了.回调函数就是将可执行的代码作为参数进行传递. 实现回调的方法 在Java中可以通过接口来实现,在C语言中可以通过函数指针来实现,C++中可以通过class-type functor,也就是重载操作符operator ()的类,在C#中可以使用Delegate委托,在Python/Perl/ML/javascript中可以直接传递函数. JDK中提供了Comparable

普林斯顿公开课:算法第0章,课程介绍

课程介绍 这门课程核心内容是算法和数据结构. 具体的算法和数据结构如下: 数据类型:堆栈.队列.背包.并查集.优先队列. 排序:快排.并排.堆排.基数排序 查找:BST.红黑BST.哈希表 图:BFS.DFS.Prim.Kruskai.Dijkstra 字符串:KMP.正则.TST.哈夫曼.LZW 高级:B树.后缀数组.最大流 为什么要学习算法 算法在各个领域中都有应用. 算法可以提高编程效率. 算法可以将现实生活中的物理公式转换成代码,算法可以模拟现实世界,然后发现世界的奥秘. 算法是很有趣的

普林斯顿公开课 算法3-3:三路快排

很多时候排序是为了对数据进行归类,比如对城市进行排序,对员工的职业进行排序.这种排序的特点就是重复的值特别多. 如果使用普通的快排对这些数据进行排序,会造成N^2复杂度,但是归并排序和三路快排就没有这样的问题. 三路快排 三路快排的基本思想就是,在对数据进行分区的时候分成左中右三个部分,中间都是相同的值,左侧小于中间,右侧大于中间. 性能 三路快排的复杂度比普通快排小,主要取决于数据中重复数据的数量.重复数据越多,三路快排的复杂度就越接近于N. 代码 public class Quick3 {

普林斯顿公开课 算法3-4:快排的应用

排序的应用 排序算法有着广泛的应用. 典型的应用有 对名称进行排序 排序MP3音乐文件 显示Google的搜索结果 按标题顺序列出RSS订阅 排序之后下列问题就变得非常简单了 找出中位数 数据库中的二分查找 找出统计数据中的异常值 在邮箱中找出重复的邮件 不是特别典型的应用有 数据压缩 计算机图形 计算生物 负载平衡 编程语言中的排序算法 java中对于基本类型使用快排,对于引用类型使用归并排序.因为归并排序很稳定,而且保证复杂度为NlgN Java.C/C++中的快排都有以下特性: 对于小的子

普林斯顿公开课 算法3-9:Comparator比较器

在前几个章节中使用了Comparable作为比较函数.比如对于字符串,就是按字母表的顺序进行排序.有时候想要换一种比较方式,该怎么实现呢? 在Java中可以使用Comparator比较器,以下代码展示了字符串之间不同的比较方式. String[] a; ... Arrays.sort(); ... Arrays.sort(a, String.CASE_INSENSITIVE_ORDER); Arrays.sort(a, Collator.getInstance(new Locale("es&qu

普林斯顿公开课 算法4-1:优先级队列API和基本实现

优先级队列是容器的一种,可以向优先级队列中添加或取出数据,取出数据时只能取出最大的数或最小的数.而其他的一些容器比如队列和栈,取出的顺序跟插入的顺序是有关的. 优先级队列的接口如下: public class MaxPQ<Key extends Comparable<Key>> { MaxPQ(); void insert(Key x); Key popMax(); boolean isEmpty(); } 优先级队列的应用 事件驱动的模拟 数字运算 数据压缩 图的查找 数论 人工

普林斯顿公开课 算法4-3:堆排

堆排的灵感源自于堆的数据结构.它是一种原地排序算法,不需要额外的临时数组. 基本思想 堆排的基本思想是: 先建立一个最大堆 将最大的元素移动到数组末尾,减小堆的大小,调整最大堆使其符合最大堆的性质 重复第二步,直到最大堆耗尽为止 第一个步骤建立最大堆的代码非常简单,只要对每个节点执行sink操作即可. 1 2 for(int k = N/2; k >= 1; k--)     sink(a, k, N); 第二个步骤也很简单,代码如下: 1 2 3 4 while(N > 1) {     e

普林斯顿公开课 算法4-4:优先级队列的应用

问题 模拟N个运动的小球,小球之间可以发生弹性碰撞 建模 硬碟模型 N个运动的质点,它们之间能发生弹性碰撞,也可以和墙壁发生弹性碰撞 每个质点有明确的位置.速度.质量.半径 没有其他外力 模型应用范围 麦克斯韦:物体的温度和微粒速度分布的关系 爱因斯坦:解释花粉的布朗运动 基本思想 基本思想就是预测小球的碰撞时间,然后将碰撞时间作为优先级队列的关键字进行排序,每次从优先级队列中取出最小的元素,进行碰撞计算,然后重新预测碰撞时间. 这里面涉及到很多物理知识,代码就不演示了. 普林斯顿公开课 算法4

普林斯顿公开课 算法1-10:并查集-优化的快速合并方法

应用 渗透问题 游戏中会用到. 动态连接 最近共同祖先 等价有限状态机 物理学Hoshen-Kopelman算法:就是对网格中的像素进行分块 Hinley-Milner多态类型推断 Kruskai最小生成树 Fortran等价语句编译 形态学开闭属性 Matlab中关于图像处理的bwlabel函数 渗透问题 一个N×N的矩阵,判断顶部和底部是否连通就是渗透问题. 下图中左侧的矩阵能渗透,右侧矩阵不能渗透. 渗透问题在电学.流体力学.社会交际中都有应用. 在游戏中可能需要生成一张地图,但是作为地图