数据结构

Introduction

Analyzing Algorithms

  1. 插入排序:与左边的元素进行比较。

  2. RAM Model

    1. 原子操作
    2. 常数时间操作
    3. 顺序执行
    4. \(t_j\) :while 循环的次数

Asymptotic Notation Divide-and-Conquer

  1. 渐进记号

    1. \(\Theta\)
    2. \(O=\leq\)
    3. \(\Omega=\geq\)
  2. 具体复杂度和抽象复杂度

    1. concrete:use RAM model,including a lot of 细节。
    2. abstract:use 渐进记号 analyze.

Solving Recurrences – 1

  1. 递归式的定义:描述具有递归调用的算法运行时间,通过小的输入上的已知的函数值来describe a function.

  2. 矩阵乘法的Divide and Conquer Algorithm

image

Solving Recurrences – 2 Sorting - 1

  1. 代入法

    1. 重复替代
    2. 观察模式
    3. 确定合适的steps
  2. 递归树
    image

  3. 主方法

    1. 第一种情况:若 \(f(n)<n^{\log_{b}^a}\),那么 \(T(n)=\Theta(n^{\log_{b}^a})\)
    2. 第二种情况:若 \(f(n)=n^{\log_{b}^a}\),那么 \(T(n)=\Theta(n^{\log_{b}^a}\log n)\)
    3. \(f(n)>n^{\log_{b}^a}\),那么 \(T(n)=\Theta(f(n))\)
  4. 循环不变性:循环执行过程中某些条件或属性始终为true的一种assertion。这些条件在循环的每次迭代中都是true的,并且在开始和结束后都是true.

    1. 不变性断言:提出的不变性假设。
    2. Initialization:循环开始之前初始状态满足所需的条件。
    3. Maintenance:每次迭代都不会破坏不变性条件,一次迭代前true,下一次迭代前也true.
    4. Termination:迭代结束时,不变性需要提供足够的信息来prove the correctness of the algorithm.
  5. 选择排序:顺次选i~l最小的即可,然后swap(i,l) 。

Sorting - 2

  1. 复杂度:

    1. concrete:算法的运行时间或所需步骤的数量,是一个具体的数值。
    2. abstract:关注算法性能的总体趋势,通常使用大O表示法。
  2. heapify:维持堆的结构。

Basic Data Structures

  1. ADTs:数据集合和操作集合的抽象。
    1. 特点
      1. 隐藏了具体的实现细节,只暴露了操作的接口。
      2. 独立于实现方式。
      3. 封装了数据结构和算法,不用关心内部的实现机制。
    2. 优点
      1. 关注操作。
      2. 不用关注如何实现
      3. 将truth和efficiency depart,因为关注的是操作的逻辑,而不是具体的实现。
    3. 与data structure的关系
      1. 抽象 vs 具体
      2. 规范 vs 实现

Data Structures - 2

散列表/哈希表

  1. 散列函数应当将一个大范围的键均匀的放到有限数量的槽位上。

  2. 冲突解决

    1. 链接法
    2. 开放寻址法
      1. 线性探测法:顺序找下一个空闲槽位。不好的点在于:多个元素连续的储存在相邻的位置上。
      2. 二次探测法:use 二次函数探测下一个空闲的位置,\(hash + i^2\) 。优点是减少聚集,缺点是实现复杂计算开销大。
      3. 双哈希:use 第二个哈希函数来确定下一个探测的位置,\(hash + hash2*i\) 。优点可以避免聚集且不会像二次探测有规律的变大。缺点实现复杂要俩哈希函数。

关于Ordered list Query Modify 一些函数的q

  1. 选择好的散列函数
    1. 哈希表的大小尽量为质数。
    2. 选择合适大小的模数。

Trees

delete:find successor point.
add:according to the rule

B-tree:

  1. defination
    1. 所有叶子depth相同。
    2. 每个内部节点有a个key和a+1个指向子节点的link
    3. p1 key1 p2 key2 ...... pn keyn pn+1,keyi 单调向上 。
    4. |keyi|keyi+1|,keyi比左边的link指向的key大,比右边的小。
    5. m阶b树,最少 \(\lceil\frac{m}{2}\rceil\) 个branches。
  2. 操作
    1. 插入:找到插入的位置进行插入,若没有上溢出,不用adjust,else 将中间元素 \(\lceil\frac{m}{2}\rceil\) 上移两边fracture。
    2. 构建:不断插入即可。
    3. 删除:删除非叶节点元素都相当于是删除叶节点元素(nxt or pre),若未下溢出无需adjust,若下溢出,兄弟够借的话借,不够的话,合并即可。

Dynamic Programing

  1. 记忆化比递推(自底向上方法)慢(因为递归的原因)

Elementary Graph Algorithms

  1. dfs中顶点的属性

    1. 颜色属性:

      1. 白色:未被访问过。
      2. 灰色:已被访问过,但还在栈中。
      3. 黑色:已被访问过,但已经不在栈中。
    2. 时间戳属性:

      1. 发现时间Discovery Time。
      2. 完成时间Finishing Time。
    3. 父属性

      1. 父节点指向其在Tree里的上一个节点。
  2. 基于dfs的边分类

    1. 树边
    2. 非树边
      1. 后向边:连接到了祖先的边。
      2. 自环:连接到了相同的点。
      3. 前向边:连接到了已经被访问过的后代。(无向图没有)
      4. 交叉边:两个点在不同的dfs树中。(无向图没有)

Strongly Connected Components & Minimum Spanning Trees

强连通分量

使用Kosaraju算法

  1. DFS记录Finishing Time.
  2. 构造反图(即转置)。
  3. 逆向图上DFS,从Finishing Time最大的点开始。
    重复2.3.得到的各个集合就是一个强连通分量。

prim&kruscal

1.safe edge,最小的可以选择的合法边。

通用算法

  1. A边集合respect(S,V-S)意味着集合A中没有边跨过该割。

    1. 初始化:随机选择一个点作为起始点。
    2. 寻找轻边
    3. update MST and 割,使得新的割still respect MST。
      重复2.3.直到MST包含所有顶点。
  2. 与prim和kruscal的关系

    1. 基于点的MST算法,管理一个increasing tree A,under the framework of 通用算法,每次扩展新边,然后将新点加入
    2. 基于边的MST算法,对于每一个点边集,通过寻找轻边来进行合并,然后update每一个点边集。
posted @ 2024-06-06 10:06  _daybreak  阅读(6)  评论(0编辑  收藏  举报