算法2A
堆
完全二叉树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6bX6siUn-1600633772860)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920194436358.png)]
- 堆是一种特殊的树型结构,称为完全二叉树
- 基本是孩子双全的
- 底层和次底层才有可能是非双全的
- 而且缺失的只能右节点
- 便于存储,任意一个节点的左右孩子有一个简明的关系
- 节点值k的左右值为:左节点:2k+1 右节点:2K+2
- 更快的写法:左:LC(k)=(k<<1)+1 右:RC(k)=(k+1)<<1
- insert(e)、getMax() 需要一个优先级priority
- 怎么实现O(n)或者log(n)的写法
-
让最大的元素位于最底层的最右边一个
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZIGV1TM-1600633772862)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920195133825.png)]
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lXXuWodc-1600633772863)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200921040202070.png)]
- 上图解释
- 第一行表示插入insert(e),
- 1.紧贴原来的缺口,假设是20,但是怎么更新它的priority?
- 2.但是它的父亲优先级却没有它高,违背了父亲必须高于孩子的优先级的原则,跟父亲交换位置,
- 3.一直到满足堆的原则
- 4.最坏的情况是一直换到根节点
- 第二行表示删除delMax
- 1.直接删除root,变成平顶
- 2.把末尾的元素倒栽到根节点位置
- 3.把左右孩子中权重更大的值作比较,与权重更大的孩子交换
- 4.反复下去,要么在某个位置停止,要么在最底层停止
- 第一行表示插入insert(e),
满二叉树
- 所有的节点都是孩子双全的
- 满二叉树是完全二叉树的一个特例
减而治之
-
贪心不同于减而治之,贪心是每一步都希望最大,减而治之,比较佛系,每一步都按照既定的步骤来进行
-
概述
减 decrease
而
治 conquer
之
-
数据规模:几十万,上百万
-
愚公移山
- 把问题简化为数据量为1的问题,然后解决
- 剩下的问题,都按照第一步的思路,拆出1的数量,然后解决,如此反复下去。
-
这是算法中很常见的一种应用策略
二分查找
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AVfXWWi6-1600633772865)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920195820812.png)]
- 预处理,从小到大排序
- 猜一下mi(中点元素)是否是自己要找的数据,如果>则减去0到mi之间的元素段,否则减去mi到末尾之间元素段。
- 红色段:思考题
- lo = mi +1 ?
- 两次判断的界桩都没有覆盖mi,那不是遗漏mi?
选择排序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sNDZiNq5-1600633772866)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920200908512.png)]
- r的前面叫前缀,r的后面一段是后缀
- 后缀是有序的,将前缀中最大的元素与r这个界桩元素交换,这样后缀可以往前前进一步,类似于减而治之里面减除数据量为1的说明。
- 最关键的一步是select
- 每一次都需要在前缀里面找出最大的元素(泛化出来的步骤,每次都是这样一个操作)
- 我们最关心的是最糟糕的复杂度
- n*(n+1)/2 O(n^2)
堆排序(优化上面的选择排序)
-
对选择排序的一种优化
-
把前缀中最大的和界桩交换
-
把前面的数据用堆组织起来
-
相当于delMax(),然后再把界桩插进去
-
-
前缀中的元素让它有一个优先级,让它用一个堆来存储它,把界桩和队首元素交换,然后再让x元素从最后开始做下滤
插入排序
- 邓公更偏爱插入排序
- 打牌的过程
- 插入排序不同于选择排序,不用数据全部到就开始排序,是在线的,来一个就处理一个
选取问题(select)
- 选择第k大的元素,注意不是选择出所有的第1大、第2大。。。。第n大的,所以不需要去排序的方法,因为排序最好的复杂度是O(nlogn),虽然之后已经是O(1)了,但是前面已经爆掉了
快速选择
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMwRD6FF-1600633772867)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920210110186.png)]
- 至少是O(n)的,因为至少要把所有的元素全扫一遍
- 随机找一个认为是第K大的元素,把比它小的放左边,把比它大的放右边
- privot一般取lo
最短路径问题
Dijkstra算法
google地图,如何实现的
- 将地图记录在计算机中
- 每一条边代表着cost,车费或邮费
- 预处理一个东西,从某个点开始到其余各个点的最短路径都找到
Dijkstra
- 迪杰斯特拉 学术界不是这么读
- 唐得胜先生
- 黛渴斯tra
principle
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zcj4KTLK-1600633772868)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920212246124.png)]
- 连通的无环的树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xhAoGnhS-1600633772869)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920212614165.png)]
- 想象将其中S点从桌面提起来
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NujTkZJ4-1600633772869)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920213115161.png)]
- 桌面没起来的点,是因为还没到它的最短距离
- 新拉起来的一个点,与它相连拉起它的那条绷直的边(cross边,图中标红的边),边上的另一个节点一定是已经拉起来的节点中的一个(绿色的点)(S、A、B),不一定是起始点(S)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Di6mq5o-1600633772870)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920214124237.png)]
- 每新拉起一个节点,下面未拉起的节点,就新多了一种新的选择
- 红边是与之前大佬连接的边,黄边是与新拉起大佬的连接的边
注意
-
dijstra的隐藏缺陷,当权重是负数
-
负权重问题
-
最致命的问题,两个点存在一条环路,循环负权重问题,无法解决,后期用动态规划
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KNSPPBeM-1600633772871)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920214651458.png)]
- 最关键的是这样一个循环
- 最后形成一个遍历树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wz3AVBBL-1600633772871)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920214845624.png)]
- 寻找新的可能,不断去更新,变红部分
为什么要用堆实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wu33ZzBJ-1600633772872)(C:\Users\liusiping\AppData\Roaming\Typora\typora-user-images\image-20200920215307384.png)]
- 始终维护了一个maximum
- minimum就是又重新生成一棵树
- delMax后,还需要更新G,F点的权重值,然后向上做上滤
- 最后生成的是树,而且是要找最小的边,所以也是一棵最小生成树,所得到的边数等于n-1,n是所有的节点数