算法图解 笔记

算法图解 笔记


第一章 算法简介

1. 二分查找

一般而言,对于包含n个元素的列表,用二分查找最多需要$ log_2n $步

2. 运行时间

线性时间:需要计算的次数和列表长度相同

3. 大O表示法

大O表示法指出了最糟情况下的运行时间

4. 一些常见的大O运行时间(从快到慢顺序):

O ( l o g 2 n ) O(log_2n) O(log2n) :对数时间,二分查找
O ( n ) O(n) O(n):线性时间,简单查找
O ( n ∗ l o g n ) O(n*logn) O(nlogn):快速排序
O ( n 2 ) O(n^2) O(n2):选择排序
O ( n ! ) O(n!) O(n!):旅行商问题

第二章 选择排序

1. 数组和链表操作的运行时间

-数组链表
读取 O ( 1 ) O(1) O(1) O ( n ) O(n) O(n)
插入 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)
删除 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)

数组支持随机访问,链表只能顺序访问。
一种混合数据结构:链表数组

2.选择排序

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。(或者将每次排序后的最大(小)元素放进新数组)

平均复杂度: O ( N 2 ) O(N^2) O(N2)
最佳时间复杂度: O ( N 2 ) O(N^2) O(N2)
最差时间复杂度: O ( N 2 ) O(N^2) O(N2)
空间复杂度: O ( 1 ) O(1) O(1)
稳定性:不稳定

第三章 递归

1. 递归函数

基线条件和递归条件

2. 栈、调用栈、递归调用栈

第四章 快速排序

1. 分治(D&C)

(1)找出简单的基线条件
(2)确定如何缩小问题的规模,使其符合基线条件

2. 快速排序

(1)选择基准值
(2)将数组分成两个子数组:小于基准值的元素和大于基准值的元素
(3)对两个子数组进行快速排序

快速排序的独特之处在于,其速度取决于选择的基准值。
最佳/平均运行时间: O ( n l o g n ) O(nlogn) O(nlogn)
最差时间复杂度: O ( n 2 ) O(n^2) O(n2)

第五章 散列表(hash table)

1. 散列表

应用:
(1)将散射表用于查找
(2)防止重复
(3)将散列表用作缓存

最优时间复杂度: O ( 1 ) O(1) O(1)

2. 冲突

处理冲突的方式很多,最简单的办法如下:如果两个键映射到了同一个位置,就在这个位置存储一个链表。但是当散列表某一位置的链表过长,散列表性能下降。

第六章 广度优先搜索

1. 广度优先搜索

可以解决两类问题:
第一类问题:从节点A出发,有前往节点B的路径吗?
第二类问题:从节点A出发,前往节点B的那条路径最短

2. 用队列实现BFS伪代码:

1  procedure BFS(G, root) is
2      let Q be a queue
3      label root as explored
4      Q.enqueue(root)
5      while Q is not empty do
6          v := Q.dequeue()
7          if v is the goal then
8              return v
9          for all edges from v to w in G.adjacentEdges(v) do
10              if w is not labeled as explored then
11                  label w as explored
12                  w.parent := v
13                  Q.enqueue(w)

第七章 狄克斯特拉算法

1. 狄克斯特拉算法——计算加权图中的最短路径

狄克斯特拉只适用于有向无环图

(1) 找出"最便宜"的节点,即可在最短时间内前往的节点。
(2) 对于该节点的邻居,检查是否有前往它们的更短路径,如果有,就更新其开销。
(3) 重复这个过程,直到对图中的每个节点都这样做了。
(4) 计算最终路径。

2. 不能将狄克斯特拉用于包含负权边的图。

如果图中包含负权边,使用贝尔曼-福德算法。

3. 算法

    A[还有要处理的节点]-->B[获取离起点最近的节点]
    B-->C[更新其邻居的开销]
    C-->D[如果有邻居的开销被更新,同时更新其父节点]
    D-->E[将该节点标记为处理过]
    E-->A

第八章 贪婪算法

1. 贪婪算法

每步都选择局部最优解,最终得到的就是全局最优解。

2. 背包问题

背包问题中,贪婪策略不能获得最优解。

3. 集合覆盖问题

4. NP完全问题

第九章 动态规划

1. 背包问题

动态规划先解决子问题,再逐步解决大问题。一般用二维网格记录子问题的状态,单元格中的值通常是要优化的值。只有子问题是离散的,并且不依赖其他子问题时,动态规划才管用。

2. 最长公共子串

3. 最长公共子序列

第十章 K近邻算法

  1. KNN用于分类和回归
  2. 提取特征
  3. 回归用于预测

##第十一章 其他算法介绍

1. 树

二叉查找树:对于每个节点,左子节点的值都比它小,而右子节点的值都比它大。平均运行时间: O ( l o g n ) O(logn) O(logn),最糟运行时间 O ( n ) O(n) O(n)。缺点是不能随机访问。
另外,可以了解红黑树、B树、堆、伸展树等。

2. 反向索引

常用于创建搜索引擎

3. 傅里叶变换

4. 并行算法

5. MapReduce

MapReduce是一种流行的分布式算法,基于映射函数和归并函数。
归并:将一个数组转换成一个元素。

6. 布隆过滤器和HyperLogLog

7. SHA(安全散列算法)

SHA是一个散列函数,它生成一个散列值——一个较短的字符串。用于创建散列表的散列函数根据字符串生成数组索引,而SHA根据字符串生成另一个字符串。
SHA可以用于比较文件、检查密码等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值