最近快速阅读了《图解算法》这本算法的入门书,对其中的一些知识点做了总结。
- 使用递归函数需要确定基线条件和递归条件
- 调用栈。在调用一个函数的时候,当前函数暂停并处于未完成状态
- 分而治之(D&C算法),找出基线条件,然后不断将问题分解,直到符合基线条件
- 快速排序比归并排序快,虽然两者都是O(n * log n) 但是快排的常量比归并排序小
- 散列表,也就是哈希表,根据是根据关键码值而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
- 广度优先搜索只能在非加权图中查找最短路径,即转折的次数最少。如果要在非负加权图中查找最短路径,可以使用狄克斯特拉算法。这是一种贪婪算法,每次都选择路径最小的点,然后更新其到邻居节点的权值和。如果图中有负权边,使用贝克曼-福德算法
- 贪婪算法,确实很贪婪
- 动态规划,最优子结构和重叠子问题
- 分治思想和动态规划的相同点是:二者都要求原问题具有最优子结构性质,都是将原问题分而治之,分解成若干个规模较小(小到很容易解决的程序)的子问题,然后将子问题的解合并,形成原问题的解。
- 分治思想和动态规划的区别是:分治是将分解后的子问题看成是相互独立的,通常用递归来做;动态规划将分解后的子问题看成是具有相互联系,有重叠部分,需要记忆,通常用迭代来做。
- 在计算样本特征之间的差距的时候,除了使用距离公式,还可以使用余弦相似度计算样本之间的角度。
- 之后可以了解:树,包括B树、红黑树、堆、伸展树;并行算法,如MapReduce;加密算法;线性规划
前三章
五种常见的大O运行时间
O(log n),也叫对数时间,如二分查找
O(n),也叫线性时间,如简单查找
O(n * log n),快排
O(n*n),选择
O(n!),旅行商问题
算法的基本认识
算法的速度指的并非时间,而是操作数的增速
讨论算法的速度时,我们说的是随着输入的增加,指其运行时间将以什么样的速度增加
算法的运行时间用大O表示法表示
O(logn)比O(n)快,当需要搜索的元素越多时,前者比后者快得越多
递归和迭代的区别:
递归是在函数里面调用自己
迭代是不断调用另一个值
递归
基线条件,指的是函数何时不再调用自己,结束递归
递归条件,指的是,函数何时调用自己
递归函数如果一直运行:
栈将不断地增大,每个程序可使用的调用栈空间有限,程序用完这些空间(终将如此)后,将因栈溢出而终止
递归指的是调用自己的函数
所有函数的调用都进入调用栈
调用栈可能很长,这将占用大量内存
调用栈(call stack)
对于这样的一个函数
def greet(name):
print("hello" + name + "!")
greet2(name)
print("getting ready to say bye")
bye()
def greet2(name):
print("how are you" + name + "?")
def bye():
print("ok bye!")
当调用greet("mary")的时候,计算机首先为该函数调用分配一块内存
使用这些内存来存储变量
当再次调用greet2("mary")的时候,计算机也为这个函数的调用分配一块内存。
计算机使用一个栈来表示这些内存块,其中第二个内存块位于第一个内存块上面,当函数调用返回的时候,栈顶的内存块弹出
当调用greet2的时候,greet只执行了一部分。调用另一个函数的时候,当前函数暂停并处于未完成状态。该函数的所有变量的值都还在内存中。
执行玩