1.算法表述
○ 自然语言(ENGLISH)
○ 算法描述语言(Pseudo-code)
○ 计算机程序语言(C++,Java)
○ 硬件设计(DSP)
2.算法的一般特性
正确性 对于符合输入类型的任意输入数据,都产生正确的输出
有效性 每一步指令能够被有效的执行,并且规定了指令的执行效果,结果应该具有的数据类型,而且是可以预期的
确定性 每一步之后都要有确定的下一步指令
有穷性 有限步内结束
大于等于0个的输入、大于等于1个的输出
3.十大排序算法及其时间复杂度
1 < logn < n < nlogn < n2 < n3 < 2n < n!
冒泡排序(Bubble Sort)
选择排序(Selection Sort)
插入排序(Insertion Sort)(扑克牌)
https://www.cnblogs.com/WuNaiHuaLuo/p/5397041.html
希尔排序(Shell Sort)(按下标的一定增量分组,对每组进行插入排序)
https://www.cnblogs.com/chengxiao/p/6104371.html
快速排序(Quick Sort)(找基准数+分治法)
https://blog.csdn.net/adusts/article/details/80882649
https://blog.csdn.net/MoreWindows/article/details/6684558
归并排序(Merge Sort)(分治思想)
https://www.cnblogs.com/chengxiao/p/6194356.html
堆排序(Heap Sort)(二叉树)
https://www.cnblogs.com/jingmoxukong/p/4303826.html
计数排序(Counting Sort)(桶排序的特殊情况)
https://www.sohu.com/a/258882297_478315
桶排序(Bucket Sort)(分治思想)
https://yq.aliyun.com/articles/652774
基数排序(Radix Sort)(”分配”和”收集”)
http://www.cnblogs.com/ECJTUACM-873284962/p/6935506.html
4.五大常用算法
分治算法
对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。
特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质
3) 利用该问题分解出的子问题的解可以合并为该问题的解
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题
应用举例:二分搜索、Strassen矩阵乘法、合并排序、快速排序、最接近点对问题、汉诺塔
动态规划算法
https://mp.weixin.qq.com/s/vEUJ7pX3yrFrl69O0QOCwQ?
与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。
由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。
与分治法最大的差别是:适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)。
动态规划是通过组合子问题的解而解决整个问题的
动态规划算法对每个子问题只求解一次,将其结果存放到一张表中,以供后面的子问题参考,从而避免每次遇到各个子问题时重新计算答案
特征:具有最优子结构和重叠子问题的性质
动态规划通常用于最优化问题
步骤:
1.描述最优解的结构
2.递归定义最优解的值
3.按自底向上的方式计算最优解的值
4.由计算出的结果构造一个最优解
贪心算法
贪心选择性质: 若一个问题的全局最优解可以通过局部最优解来得到,则说明该问题具有贪心选择性质
优化子结构: 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
基本思路:
1.建立数学模型来描述问题
2.把求解的问题分成若干个子问题
3.对每一子问题求解,得到子问题的局部最优解
4.把子问题的解局部最优解合成原来解问题的一个解
特征:
局部最优策略能导致产生全局最优解
存在的问题:
1.不能保证求得的最后解是最佳的
2.不能用来求最大或最小解问题
3.只能求满足某些约束条件的可行解的范围
贪心算法和动态规划的区别:
1.贪心算法是自顶向下的,而动态规划则是自底向上的
2.贪婪算法总是找当前最大值,动态规划则是根据子问题的比较找最优解的
回溯算法
类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
基本思想:在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)
分支限界算法
类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解
与回溯法的区别:
回溯法深度优先搜索堆栈活结点的所有可行子结点被遍历后才被从栈中弹出找出满足约束条件的所有解;
分支限界法广度优先或最小消耗优先搜索队列、优先队列每个结点只有一次成为活结点的机会找出满足约束条件的一个解或特定意义下的最优解
排序算法的正确性
分治法
二分搜索
矩阵乘法、矩阵乘法Strassen’s 算法
最近点对问题
随机化算法
统计算法、蛮力法
贪婪算法
图的算法
最小生成树:
https://blog.csdn.net/a2392008643/article/details/81781766
单源最短路径
全成对最短路径
最大网络流:
https://www.cnblogs.com/xzxl/p/7348335.html
https://blog.csdn.net/lzoi_hmh/article/details/74940366
最小割:
https://www.cnblogs.com/dyzll/p/5887266.html
https://huobengle.iteye.com/blog/1386794
图
G = (V, E)
V:节点
E:边
有向图
无向图
无回路图
图的连接
邻接表
相邻矩阵
有权图
DFS、BFS:
https://blog.csdn.net/weixin_40953222/article/details/80544928
https://www.jianshu.com/p/bff70b786bb6
边
拓扑排序:
https://www.jianshu.com/p/e41985e2eaf0
https://blog.csdn.net/qq_38984851/article/details/82844186
最长公共子序列:
https://blog.csdn.net/someone_and_anyone/article/details/81044153
[动态规划]
https://blog.csdn.net/u013921430/article/details/79299678
https://www.cnblogs.com/zlm-jessie/p/5664562.html
漫画:
https://www.jianshu.com/p/00cbd9e90aea
https://blog.csdn.net/nakiri_arisu/article/details/79341527
深度优先搜索、拓扑排序都不唯一