时间复杂度:O(n) O:代表忽略重要项以外的内容。
数据结构:
1、链表:数据呈线性排列的数据结构。数据一般是分散存储于内存中的。
分类:
- 基本链表
- 循环链表(环形链表)
- 双向链表:有两个缺点,一是指针数的增加会导致存储空间需求增加;二是添加和删除数据时需要改变更多指针的指向
2、数组:数据呈线性排列的数据结构。数据按顺序存储在内存的连续空间内。
3、栈:线性排列。后进先出(LIFO:Last in First out)。
在栈中,添加和删除数据的操作只能在一端进行,访问数据也只能访问到顶端的数据。
4、队列:线性排列,先进先出(FIFO:First in First out)
数据的添加分别在两端进行,不能直接访问位于中间的数据,必须通过出队操作将目标数据变成首位后才能访问
5、哈希表:
- 由键(key)和值(value)组成的数据。
- 从头开始查询的操作叫作“线性查找”。
- 计算哈希值,计算对应键的哈希值对将要存放的数组的长度进行取余操作(mod运算),得到将放在数组的位置,若位置冲突,可使用链表在已有数据的后面继续存储新的数据
6、堆:
- 堆是一种图的树形结构,被用于实现“优先队列”。
- 优先队列是一种数据结构,可以自由添加数据,但取出数据时要从【最小值】按顺序取出。
- 堆中的每个节点最多有两个子节点。节点的排列顺序为从上到下,同一行里则为从左到右
- 堆中存储数据的规则:子节点必定大于父节点。因此,最小的值被存储在顶端的跟节点中。
- 添加数据时,要在堆的最后添加数据,数据会一边比较它与父节点的大小,一边向上移动,直到满足堆的条件为止
- 取出数据后,要将最后的数据移到最顶端,然后一边比较它与子节点的数据大小,一边向下移动,直到满足堆的条件为止。
7、二叉查找树:
-
又叫二叉搜索树或二叉排序树,是一种数据结构,采用了图的树形结构。
-
每个节点最多有两个节点。
-
两个特性:
- 每个节点的值均大于其左子树上任意一个节点的值
- 每个节点的值均小于其右子树上任意一个节点的值
-
二叉查找树的最小节点要从顶端开始,往其左下的末端寻找。
-
删除数据时:
- 若没有子节点,则直接删除
- 若只有一个子节点,先删除目标节点,将子节点移动到被删除节点即可
- 若有多个子节点,先删除目标节点,递归查找左子树中最大节点移动到被删除节点。
-
查找数据时:从顶端开始往下查找,和添加数据时一样,小于该节点的值则往左移,大于则往右移
排序:
1、冒泡排序:冒泡排序就是重复“从序列【右边】开始比较相邻两个数字的大小,再根据结果交换两个数字的位置”这一操作的算法。
2、选择排序:选择排序就是重复”从待排序的数据中寻找最小值,将其与序列最左边的数字进行交换“这一操作的算法。在序列中寻找最小值使用的是【线性查找】
3、插入排序:
- 插入排序是一种从序列左端开始依次对数据进行排序的算法。
- 在排序的过程中,左侧的数据陆续归位,而右侧留下的就是还未被排序的数据。
- 插入排序的思路就是从右侧的未排序区域内取出一个数据,然后将它插入到已排序区域内合适的位置上
4、堆排序:
- 特点是利用了数据结构中的堆。
- 在堆中存储所有数据,并按降序来构建堆 -》将跟节点(最大值)取出放在数组最右侧 -》重新构建堆 -》重复上述操作直到排序完成
5、归并排序:
- 归并排序算法会把序列分成长度相同的两个子序列,当无法继续往下分时(也就是每个子序列中只有一个数据时),就对子序列进行归并。
- 归并指的是把两个排好序的子序列合并成一个有序序列。该操作会一直重复执行,直到所有子序列都归并为一个整体为止。
6、快速排序:
-
快速排序算法首先会在序列中【随机】选择一个基准值(pivot),然后将除了基准值以外的数分为“比基准值小的数”和“比基准值大的数”这两个类别,再将其排序成下列形式
* 比基准值小的数】基准值【比基准值大的数】
接着,对两个“【】”中的数据进行排序之后,整体的排序便完成了。
对“【】”里面的数据进行排序时同样也会使用快速排序。
快速排序是一种“分治法”。它将原本的问题分成两个子问题,然后再分别解决这两个问题 不过,解决子问题的时候会再次使用快速排序,甚至在这个快速排序里仍然要使用快速排序。只有在子问题里只剩一个数字时排序才算完成。
数组的查找:
1、线性查找:在数组中从头开始依次往下查找。
2、二分查找:
- 只能查找已经排好序的数组。
- 二分查找通过比较数组中间的数据与目标数据的大小,可以得知目标数据是在数组的左边还是右边。重复该操作就可以找到目标或者判定目标不存在。
3、如果对时间复杂度要求有log,一般都需要用到二分查找
图的搜索:
- 有向图:给边加上箭头,就叫做【有向图】
- 无向图:边上没有箭头的图便是【无向图】
2、加权图:对称权重和非对称权重
3、图的搜索指的就是从图的某一顶点开始,通过边到达不同的顶点,最终找到目标顶点的过程。
根据搜索的顺序不同,图的搜索算法可分为【广度优先搜索】和【深度优先搜索】
- 广度优先搜索:假设一开始位于某个顶点(即起点),此时并不知道图的整体结构,而我们的目的是从起点开始顺着边搜索,直到到达指定顶点
- 在此过程中每走到一个顶点,就会判断一次它是否为终点 - 候补顶点是用“先进先出”的方式管理的 - 特点是从起点开始,由近及远进行广泛的搜索。因此,目标顶点离起点越近,搜索结束得就越快 - 深度优先搜索:
- 目的是从起点开始搜索直到到达指定顶点。
- 深度优先搜索会沿着一条路径不断往下搜索直到不能再继续为止,然后再折返,开始搜索下一条候补路径。
- 候补顶点是用“后入后出”的方式管理的
- 广度优先搜索选择的是【最早】成为候补的顶点,因为顶点离起点越近就越早成为候补,所以会从离起点近的地方开始顺序搜索。
- 深度优先先搜索选择的则是【最新】成为候补的顶点,所以会一路往下,沿着新发现的路径不断深入搜索。
4、贝尔曼-福特算法:
- 贝尔曼-福特算法是一种在图中求解最短路径问题的算法。
- 最短路径问题就是在加权图指定了起点和终点的前提下,寻找从起点到终点的路径中权重总和最小的那条路径。
- 被选中的边两端的权重为“顶点原本的权重+边的权重”,分别计算两个方向的权重,选出最小的。
- 无向图要两个方向都计算,有向图只要按照边所指向的那个方向来计算就可以了。
- 将图的顶点数设为n,边数设为m,时间复杂度为:
该算法经过n轮更新操作后就会停止,而在每轮更新操作中都需要对各个边进行1次确认,因此一轮更新所花费的时间就是O(m),整体的时间复杂度就是O(nm) 遇到对顶点进行n次更新操作后仍能继续更新的情况(例如闭环中边的权重总和是负数),就可以直接认定它为“不存在最短路径”
5、狄克斯特拉算法:求解最短路径问题的算法。
- 计算各个候补顶点的权重方法:目前所在的顶点的权重 + 目前所在顶点到候补顶点的权重。
- 从离起点近的顶点开始,按顺序求出起点到各个顶点的最短路径。也就是说,一些离终点较远的顶点的最短路径也会被计算出来,这些其实是无用的。
- 如果闭环中有负数权重,就不存在最短路径。
- 有负数权重时 不能使用狄克斯拉算法,因为会计算出一条错误的最短路径,应该使用贝尔曼-福特算法
6、A*算法:A-Star 算法。
-
会预先估算一个值,并利用这个值来省去一些无用的计算。
-
A* 算法不仅会考虑从起点到候补顶点的距离,还会考虑从当前所在顶点到终点的估算距离。这个估算距离可以自由设定。
-
若能得到一些准确的启发信息,即各个顶点到终点的大致距离(这个距离不需要准确的值)我们就能使用A* 算法,若无法估算,则不能使用
- 安全算法
- 数据传输过程中的问题及解决方法
| 问题 | 解决方法 |
|---|---|
| 窃听 | 加密 |
| 假冒 | 消息认证 OR 数字签名 |
| 篡改 | 消息认证 OR 数字签名 |
| 事后否认 | 数字签名 |
| “数字签名”技术存在“无法确认公开密钥的制作者”这一问题。要想解决这个问题,可以使用“数字证书”技术 |
-
加密基础:加密就是数据经过某种运算后,变成计算机无法理解的数的过程
加密后的数据被称为“密文”
把密文恢复健康为原本数据的操作叫作“解密”
对计算机来说,数据就是一串有意义的数字罗列。密文也是数字罗列,只不过它是计算机无法理解的无规则的数字罗列。
在加密运算上会用到“密钥”。所以加密就是用密钥对数据进行数值运算
将数据变成第三者的计算机无法理解的形式,然后再将其恢复成原本数据的一系列操作就是加密技术 -
哈希函数:哈希函数可以把给定的数据转换成固定长度的无规律数值。
哈希值虽是数字,但多用十六进制表示
哈希函数实际上是在计算机内部进行着某种运算的
哈希函数的特征:- 第一个特征是输出的哈希值数据长度不变(无论输入的多大或多小)
- 第二个特征是如果输入的数据相同,那么输出的哈希值也必定相同(在使用同一算法的前提下)
- 第三个特征是即使输入的数据相似,但哪怕它们只有一比特的差别,那么输出的哈希值也会有很大的差异
- 第四个特征是即使输入的两个数据完全不同,输出的哈希值也有可能是相同的,这种概率很低,被叫做“哈希冲突”
- 第五个特征是不肯呢个从哈希值反向推算出原本的数据(输入和输出不可逆)
- 第六个特征是求哈希值的计算相对容易
-
共享密钥加密:共享密钥加密是加密和解密都使用相同密钥的一种加密方式。也叫做“对称加密”
共享密钥加密存在“密钥分配问题”,由于加密解密使用相同密钥,无法确保密钥的传输是否安全,解决这个问题,可以使用“密钥交换协议”和“公开密钥加密”两种方式 -
公开密钥加密:
- 公开密钥加密是加密和解密使用不同密钥的一种加密方式。也叫做“非对称加密” 。加密用的密钥叫作“公开密钥”,解密用的叫作“私有密钥”。
- 公开密钥存在公开密钥可靠性的问题,就是A无法判断收到的公开密钥是否来自B。要想解决这个问题,要用到“数字证书”
- 公开密钥还有一个问题就是加密和解密都比较耗时,所以这种方式不适用于持续发送零碎数据的情况。要解决这个问题,需要用到“混合加密”
- 通过中途替换公开密钥来窃听数据的攻击方式叫作“中间人攻击”。
5、混合加密
- 共享密钥加密存在无法安全传输密钥的密钥分配问题,公开密钥加密又存在加密解密速度较慢的问题。结合这两种方式以实现互补的一种加密方法就是混合加密
- 在混合加密中,要用处理速度较快的共享密钥加密对数据进行加密。不过,加密时使用的密钥,则需要用没有密钥分配问题的公开密钥加密进行处理。
- 混合加密的流程:加入A要发送数据给B
- A使用共享密钥加密数据
- B使用公开密钥生成公开密钥和私有密钥,将公开密钥发送给A
- A使用B发送过来的公开密钥进行加密要解密使用的共享密钥并发送给B
- A将共享加密后的数据发送给B
- B收到A发送过来的用公开密钥发送过来的共享密钥,使用自己手里的私有密钥进行解密,得到共享密钥,并解密A发送过来的数据
6、迪菲 - 赫尔曼密钥交换
- 迪菲 - 赫尔曼密钥交换是一种可以在通信双方之间安全交换密钥的方法。这种方法通过将双方共有的【秘密数值】隐藏在公开数值相关的运算中,来实现双方之间密钥的安全交换。
- 假设有一种方式可以合成两个密钥,这种合成方式有三个特征:(使用这种方式来合成密钥P和密钥S,就会得到由这两个密钥的成分所构成的密钥P-S)
- 即使持有密钥P和合成的密钥P-S,也无法把密钥S单独取出来
- 不管是怎样合成而来的密钥,都可以把它作为新的元素,继续与别的密钥进行合成。
- 密钥的合成结果与合成顺序无关,只与用了哪些密钥有关。
- 迪菲 - 赫尔曼密钥交换利用了数学难题“离散对数问题”
7、消息认证码
- 消息认证码可以实现“认证”和“检测篡改”这两个功能。
- 密文的内容在传输过程中可能会被篡改,这会导致解密后的内容发生变化,从而产生误会。消息认证码就是可以预防这种情况发生的机制。
8、数字签名
- 数字签名不仅可以实现消息认证码的认证和检测篡改功能,还可以预防事后否认问题的发生
- 数字签名是只有发信人才能生成的,因此使用它就可以确定谁是消息的发送者了。
- 数字签名的生成使用的是公开密钥加密
- 数字签名存在的问题:虽然使用数字签名后B会相信消息的发送者就是A,但实际上也有kennel是X冒充了A。解决方案是使用“数字证书”。
9、数字证书
- 消息发送者A要先向认证中心(Certification Authority CA)申请发行证书,证明公开密钥确实由自己生成。
- 消息认证中心会使用自己的私有密钥根据A的资料生成数字签名发送给A,这就是A的数字证书,里面包含A的资料和邮箱。
- A将作为公开密钥的数字证书发送给了B
- B收到数字证书,确认证书里的邮件地址是A的地址,向认证中心获取公开密钥
- B对证书内的签名进行验证,判断它是否为认证中心给出的签名。从证书中取出A的公开密钥
聚类
- 聚类就是在输入为多个数据时,将“相似”的数据分为一组的操作。一个组就叫做一个“簇”。
- 如何定义相似:
- 定义数据间的差异:根据数据类型不同,定义该数据是否“相似”的标准也不同。具体来说就是要对两个数据之间的“差距”进行定义。
- 复合条件的算法:设定什么样的条件取决于进行聚类的目的。
K-means算法:是聚类算法中的一种,它可以根据实现给定的簇的数量进行聚类。
- 由于k-means 算法需要事先确定好簇的数量,所以设定的数量如果不合理,运行的结果可能会不符合我们的需求。
- 如果对簇的数量没有明确要求,那么可以事先对数据进行分析,推算出一个合适的数量,或者不断改变簇的数量来实验k-means算法。
- 即使簇的食量相同,只要随机设置的中心点最初的位置不同,聚类的结果也会产生变化。因此,可以通过改变随机设定的中心点位置来不断尝试k-means算法,再从中选择最合适的聚类结果。
其他算法
- 欧几里得算法
- 又称辗转相除法。用于计算两个数的最大公约数,被称为世界上最古老的算法。
- 操作流程:
- 首先用较小的数除较大是数字,求出余数。
- 接着用除数和余数进行mod预算。
- 重复上个操作,直到余数为0
- 余数为0 时,最后一次运算中的除数就是两个数字的最大公约数。
- 欧几里得算法,只需要重复做除法便能求得最大公约数。
- 素行测试:
- 素行测试是判断一个自然数是否为素数的测试。
- 素数就是只能被1和自身整除,且大于1的自然数。
- 费马测试:被称为概率性素行测试,它判断的是”某个数是素数的概率大不大“。
- 根据是否满足费马小定理来判断一个数是否为素数的方式就是”费马测试“
- 费马小定理:如果P是素数,那么所有比P小的数n都满足【n mod p = n】这个条件。
- 单丝反过来,即使所有n都满足条件,P也又可能不是素数。因为在极低概率下会出现所有n都满足条件的合数(非素数的自然数,叫作“卡迈克尔数”,也叫“绝对伪素数”)。
- 网页排名
- 网页排名是一种在搜索网页时对搜索结果进行排序的算法
- 网页排名就是利用网页之间的链接结构计算出网页价值的算法。
- 汉诺塔:汉诺塔是一种移动圆盘的游戏,同时也是一个简单易懂的递归算法应用示例。