数据结构&贪心(二) by邓俊辉老师

数据结构&贪心(二)

BST binary search tree 二叉搜索树
对一个二叉搜索树,从根节点开始比较大小搜索。
任意节点:左后代比根节点小、右后代比根节点大。左小右大。
BBST:balanced binary search tree 平衡二叉树。
对于深度比较深的节点,步骤和时间会花费比较多一些。
对于树进行平衡化,深度比较平均

散列表-哈希表 hashtable
怎么去做这么一个映射 比如:取模 mod (%) 一般M为素数散列表的长度
hash(key) = hey % M
dictionary map 的底层就是一种 hashtable

Huffman Tree 哈弗曼树
选择两个权重最小的树,将它俩和二为一。
(如何有效地组织?) 组成一个vector/list
取出两颗树,在插入。一共要和n-1次。此外还要每次去寻找最小的两个值。遍历复杂度为n
此时复杂度为:n*(n-1 ) 即为 O(n^2)

寻找数据最小值–降低算法复杂度的方法
若将数据排成三角形(堆)的形式:
能够找到最小值、最大值、getMin()、delMin() -> 此时的复杂度O(logn)
底数一般默认为常数2,不写。即使写了,由于常数对其无影响,而忽略不计。
n=1000 时 O(n)1000 O(logn) 1024(若2为底)->10
堆Heap 一种优先级队列。优先队列Priority Queue -> 堆 Heap
insert() getMax()
max或min 会放在堆顶的位置。最容易获得。

运用栈&队列进行Huffman树的构建: 与heap构建Huffman树同样都是O(nlogn)
将词频率最大的依次push进入栈中 此处最优的排序复杂度为O(nlogn)
pop取出两个次大的。将其频次之和 enqueue
每次均在栈和队列中、寻找两个最小的。2+2四个元素就可以。每一次的算法复杂度O(4)->O(1)
n-1次的话,算法复杂度为 O(n) 线性的复杂度
一共有四种情况:1、栈顶两个元素pop出来 2、栈顶pop与queue中的各一个 3、queue

最小生成树MST(minimum spanning tree)

连通性:任何两个节点均要连通。
规划航线、路程—>有权图(network)
原则 :边不能太少要保证连通性,不能有环路。 每条边均有权重。
找到最小的这样一个MST使权重最小。
如何寻找Prim(人)寻找到了一种方法。cut\cross
cut(割集):U V\U(去除了)
边(三类):各自域内;连接两个域的(桥\连接边\cross ) || 点分为:2类
任何一个树,有n个节点,必有n-1条边。

任何一个cut后的最小权重跨域边都会出现在(一个)MST中
操作思路:
将将一个点作为U 其余均为其割集(V\U)。
直接取出 该点相连的最小权重边。
加入这条最小权重边,使得U扩充为两个点。将其余作为割集。
确认第二条最小权重边
重复之前的过程即可寻找到最小生成树MST
(注意最小生成树可能不止一颗。起点选得不同、生成的树也不太相同。)

因为无向有权图可以转化为对称的二维矩阵。network
在第一行(第0个节点)寻找权重最小的另一编号点。
在这个权重最小的点所在的行列中寻找最小的那个编号。
将该编号点也加入。一共有两个编号。
将这两个点,所在的行列中寻找权重最小的点。
重复之前的过程

Prim算法 : Heap
采用Heap(堆)数据结构去实现。一种优先级队列。(实际上只用一个数组就可以实现)
在所有的跨边中寻找到最短的,让每一个下面的点都去计数(他们自己的权重-距离)
dist(v)= min {|v,u| } 即待连接的与上面已生成的树的最小记录。
只需要调用delMin()把最小权重的那条边取出来。时间成本O(logn)。
整个Prim算法的时间复杂度为O(n logn)

Kruskal算法:sorting by weight
优先选择权重最小的那条边。这条权重最小的边应该会出现在所有的MST中。(利用Prim比较好理解)
然后再倒数第二条权重的边也会被MST采用。
分析:最短边有三种情况1、全在U里面
2、跨域(先让最短边包进去、次短边第二次包进去)3、全在另一半割集中。
但是第三条最短边则不一定了。需要符合一定条件才能加进来。(因为第三条边加进去很有可能会成环)
该条件是:新引入的这条边是否会形成环路。
若这条边所连接的顶点、来自于同一棵树表明他们并不安全、会形成环路。
若来自不同的树则表明是可以加入的
该算法对于稀疏图是非常好的。因为出现在同一个现存树中的概率比较小。

难点分析:如何查找?是否在同一个树中。
采用一种数据结构:并查集Union-find
查找一个元素,寻找到以后,返回其相应的值。
若在同一树中,则返回同一值。
若不在同一棵树中,则在将这两个集合和在一块(union)

采用list链表数据结构 link方式

此算法为O(n) quick-find slow-union
quick-find 在常数时间O(1)内查询到
union(7,4)——>再直接将4改为7.因为数组的下标已经标识了其位置。
slow-union 需要把所有的元素来回搬,复杂度会比较高、时间会收到惩罚。O(n)

此算法为O(logn) quick-union slow-find
quick-union
确定是哪一组的方式?由link决定,由父节点确定–若自己与父节点相等则为班长。
实现union:将一个班的班长重新归属到一个新的班长。其复杂度为O(logn)
slow-find 取决于该点在此树中的深度。一般其复杂度为O(logn)
最好组成一个班的树的结构高度为2 ,仅两层,O(1)就可以到班长。
改进union实现浅层的tree。
A班、B班。将深度浅一些的树归类到深度深一些的树中。时间复杂度为O(logn)
find操作表面看是一种静态的操作复杂度为 logn。

Path Compression(路径压缩):改变为一种动态操作、将寻找的路径folding起来。
逐渐减小树的深度,将自己的标签直接链接到班长上即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值