数据结构与算法丨期末复习

为了帮助自己更好地梳理、记忆书中的概念,写了这样一个大杂烩一般的博客。


一些在习题解析看到的做题方法

证明题:

  • 数学归纳法
  • 减治,如确定了一个子结论就把这些元素/点/边删除

计算复杂度:

  • 自己造的概念,如势能分摊分析
  • Fibonaccian数的利用,也许涉及递推+规模差为1,都可以利用到Fib数

算法设计:

  • 消除歧义性:数据都是整数时加上一定的小数(注意字长不要超);合成数,取作向量,可以明确依照字典数比大小。总之就是,在保障原有正确性的时候(偏序性、和最小等等),修正一下数据

图与图的应用

一些要点整理

  • 邻接矩阵/邻接表(点-点)与关联矩阵(点-边)的性能
  • DFS树
  • BFS树
  • 拓扑排序
  • 优先级搜索

BFS算法

  • 距离树根的深度在辅助队列中单调排列,辅助队列中的点的深度相差不超过1。
  • 算法的时间复杂度为O(n+e)。
  • 无向图/有向图具有两种边,TREE和CROSS,TREE连接的点dist相差1,CROSS连接的点dist至多相差1。

DFS算法

  • 算法的时间复杂度为O(n+e)。
  • 对于无向图有两种边的类型,TREE和BACKWARD;对于有向图有四种边的类型,TREE(v的工作区间完全cover掉u且v指向u)、FORWARD(同TREE但有别的工作区间隔在中间,见P577)、BACKWARD(v的工作区间完全cover掉u但u指向v)、CROSS(两者工作区间完全无交),具体例子可以见讲义P574。(记当前循环的点为v,其邻点为u)

优先级搜索

  • 即给每个点维护一个优先级数,生成树的时候优先遍历优先级数高的邻点。
  • 时间主要消耗在遍历全图+更新优先级数两重循环上,时间复杂度为O(n2)。
  • Prim算法:每次将距离当前树距离最小的一个点加入当前树,构造MST。优先级数就是与当前树的最短距离。算法正确性证明:每一割的极短跨边都会被一MST采用;
  • Kruskal算法
  • Dijkstra:从起点s开始,树的规模每增加1,更新新加入点的邻点的优先级数。优先级数是与起点s的最短距离。生成最短路径树。

其他的图算法

  • BCC的判定:dTime与hca+栈。时间复杂度为O(n+e)。
  • Kruskal算法:将边从短到长排列,贪心遍历,若组成回路则跳过。并查集算法。时间复杂度O(ne)。
  • Floyd-Warshall算法:通过最短路径矩阵实现,动态规划填表法。时间复杂度O(n3)。

二叉搜索树以及应用

一些要点整理

  • 基本接口:查找/插入/删除(由谁来接替?两种情况)
  • 保障平衡:BBST和AVL

BBST

  • zig/zag保障BST的等价性——上下可变,左右不乱。
  • zig:与左儿子一起右转。zag:与右儿子一起左转。旋转的后果:左/右子树的高度至少各变化1。

AVL Tree

  • 高度为h的AVL树至少含有S(h)=fib(h+3)-1个结点。
  • AVL的重平衡:插入可能带来大规模的失衡,而删除至多带来一次失衡。插入的复衡操作只需解决最先失衡的即可控制住,而删除的复衡操作解决了失衡的之后,后面反而会带来一连串的失衡。更直观的方法是3+4重构。通过单旋和双旋使AVL复衡。

KD-Tree

  • 一维情况:结构上,一棵子树对应一个一维的字区间,而根结点存放的是区间的“中点”(为转弯提供路标),即左子树的最大值。首先通过二分查找对应到一个线性区间的左右端点。从它们的LCA开始,向区间左/右断点走的过程中,每次左/右拐的时候汇报出右/左子树,则区间中的所有点被汇报出来。
  • 复杂度分析初始化的时间复杂度为O(nlogn),每次查询的时间复杂度为O(logn),空间复杂度为O(n)。关键码的存储可能重复,但是空间渐进复杂度并没有因此增加。
  • 二维情况:结构上,一棵子树对应一个二维点集(&一个区域),左右子树根据x/y方向来平分点集。查找平面内某个区域对应的点时,则递归查找。与一维情况类似,真正的存储位置位于叶子,内部结点只提供指明区域的作用。
  • 复杂度分析初始化的时间复杂度为O(nlogn),每次查询的时间复杂度为 O ( n + r ) O(\sqrt n+r) O(n +r),空间复杂度为O(n)
  • 多维情况:讲义P763。

Multi Level Search Tree

  • 首先根据x坐标信息生成一棵x-tree,每棵子树代表的是一个根据x坐标信息划分的区间。而每个结点挂着一棵y-tree,储存该区间内所有点的y坐标信息。查找时,先在x-tree找到对应的x区间,再在对应的y-tree里找到y信息。
  • 复杂度分析初始化的时间复杂度为O(nlogn),查询的时间复杂度为O(log2n+r),空间复杂度为O(nlogn)
  • 多维情况:讲义P773。

高级搜索树

Splay Tree

  • 单层伸展时间复杂度 Ω ( n ) \Omega(n) Ω(n),逐层伸展时间复杂度O(logn)。伸展树的所有基本操作接口的分摊时间复杂度都为O(logn)。
    数据结构与算法丨期末复习_第1张图片

B-Tree

  • 插入/删除导致的上溢/下溢的复杂度都可能达到O(h),但是分摊的时间复杂度都是O(1)
    数据结构与算法丨期末复习_第2张图片

红黑树

  • 拓扑结构的变化不超过O(1)。
  • 四条规则:树根必为黑色;外部结点必为黑色;红结点只有黑孩子;外部结点到根的黑深度相等。
  • 等价(2,4)B树。
  • 插入红结点,双红修正。至多logn次染色,1次结构调整
    数据结构与算法丨期末复习_第3张图片
  • 删除黑结点,双黑修正。至多logn次染色,1次结构调整
    数据结构与算法丨期末复习_第4张图片
  • 但是,==在分摊意义下,红黑树重染色的次数为O(1)。

词典

  • 两项基本任务:精心设计散列表和散列函数,尽可能降低冲突的概率;制定可行的预案,以便发生冲突时,能够尽快予以排解。
  • 桶排序
  • MaxGap:相当于用n个桶给n个数做桶排序,时间复杂度O(n)
  • 桶排序的应用:基数排序,整数排序,计数排序。
  • 跳转表空间复杂度expected-O(n),查找的时间复杂度expected-O(logn)

优先级队列

  • 堆序性:由顶向下满足顺序。分为小顶堆、大顶堆等等。
  • 复杂度分析:插入和删除时会上滤以及下滤,时间复杂度O(logn)。事实上,平均复杂度为O(1)。
  • Floyd建堆法:自下而上的下滤,时间复杂度是优秀的O(n)
  • 锦标赛树空间复杂度O(n),每次取出最大之后时间复杂度O(logn)。其对于堆排序的优势在于比较次数少,堆排序每层的下滤都要与两个孩子比较,Floyd总的比较次数略少于2n。
  • 左式堆:只满足堆序性,合并的时间复杂度是O(logn)。而插入和删除都可以用merge来实现。

排序

桶排序

  • 适用情况:数多,范围小,重复元素多。采用了循秩访问的方法,而非CBA。
  • 利用保序的hash函数放进散列中对应的位置,最后遍历输出散列即可。
  • 时间复杂度O(n),空间复杂度O(n+m),其中m为数据范围

基数排序

  • 从低位到高位做桶排序(10个桶)。
  • 设最高位数是t,若t是常数,时间复杂度O(n)

整数排序

  • 适用情况:大集合+小数据数的对数密度为O(1),n个数来自[0, nd)。
  • 将数转为d位的n进制数(用数组装的),接着做d次桶排序。
  • 时间复杂度O(n)

计数排序

  • 使用情况:小集合+大数据,重复元素多。
  • 过程:分桶并统计每个数的数量;自前向后扫描各同,确定每个数的秩区间;自后向前扫描元素,对应桶的计数减1,即是该元素最终的秩。
  • 时间复杂度O(n)

堆排序

  • 不断调用delMax(),时间复杂度为O(blogs)

希尔排序

  • 减量递增。时间复杂度随每次序列不同而不同。

你可能感兴趣的:(数据结构与算法)