Find_Depth和Link的实现
来源:互联网 发布:java.api 编辑:程序博客网 时间:2024/05/09 15:50
在编译器的实现等应用中需要用到上述两类指令.
问题是Find-Depth指令如果不具路径压缩功能,则执行O(n)条Find-Depth指令,最坏情况下时间复杂度为O(n2);但如果采用具有路径压缩功能的Find-Depth指令,则原先树中在被压缩路径上的各结点深度会发生改变,如不采取其它措施,对其中某结点执行Find-Depth指令时,就会得到错误的深度信息。如果我们给每个结点增加一个字段记录其在原树中的深度,这样,虽可在O(1)时间完成一条Find-Depth指令,但在执行Link指令时,由于以r为根的子树中结点的深度全部发生了变化,我们势必要修改该子树中所有结点的深度字段。此工作量很大,最坏情况下,O(n)条Link指令的时间复杂度也为O(n2);为了既能求得各点在原先树中的正确深度、又能使时间复杂度较小,我们需要使用具有路径压缩功能的Find-Depth指令;同时我们还需要采取一些辅助手段来保证深度计算的正确性。为此,我们对每个结点v增加2个字段(Count[v]和Weight[v]),并把经过改造的此类结点和树所构成的森林称为D-森林。
一、问题说明
问题描述
编写能实现上述功能的Link(v,r)指令程序,不要使用全局变量,设初始时两森林均由单结点树构成。上机依次执行:Link(2,1), Link(3,2), Link(5,4), Link(4,3), Link(7,6),Link(9,8),Link(8,7), Find-Depth(6), Link(6,5), Find-Depth(4), Find-Depth(7)。 打印或抄写每条指令执行后各点的Weight值,画出其时的两种森林。
二、程序功能说明以程序演示
程序功能说明
find_depth(i)主要是找到D森林根节点编号和i节点深度
link(v, r) 将以r链接到v,合并两棵树
程序演示结果
输入 : dtree.link(2,1);
dtree.link(3, 2);
dtree.link(5, 4);
dtree.link(4, 3);
dtree.link(7, 6);
dtree.link(9, 8);
dtree.link(8, 7);
dtree.find_depth(6)
dtree.find_depth(4)
dtree.find_depth(7)
输出结果:(注意下,这里的深度表示原森林的深度)
6的深度:3
weight[1]:1 weight[2]:7 weight[3]:-1 weight[4]:1 weight[5]:-3 weight[6]:3 weight[7]:2 weight[8]:1 weight[9]:-7
4的深度:5
7的深度:2
深度 权值
三、算法设计
find_depth(i)返回D森林根节点编号和i节点深度,它的实现如下所示,要注意几点:
1. 如果是根节点,一个参数是D森林根节点编号,另一个为weight为0
2. i的深度=weight[i] + i的父节点的weight + i的父节点的父节点的weight+ ... + 一直到D森林根节点
3. 第一次find需要经过路径压缩O(n)次需要O(n*G(n))
link(v, r) 将以r链接到v,合并两棵树,它的实现如下所示,但同样也要注意几点:
1. 首先要获得D森林v的根节点编号和D森林r的根节点编号以及v节点深度
2. 如果count[rootOfV]>= count[rootOfR]则将r所在D森林中的根rootOfR(r')指向v所在D森林中的根rootOfV(v')
3. 新weight[rootOfR]-旧weight[rootOfR]+weight[rootOfV]=depth(v) +1
4. 如果count[rootOfV]< count[rootOfR]则v’接到r’上
5. 需要修改两处地方:新weight[rootOfR] - 旧weight[rootOfR] = depth(v) + 1 和旧weight[rootOfV] + 新weight[rootOfV] +weight[rootOfR] = depth[v]
四、实验结果分析
注意一下,在实现find_depth的时候使用到了find,find实施带权路径压缩,我们这里使用递归的形式,O(n)次指令的时间复杂度为O(n*G(n))
对于实验结果,我们可以通过验证的方式来看是否正确,6、4、7的深度分别为3、5、2这是正确的,因为原树是以9为根,然后其他节点是链式连接的,如下图所示
对于权值我们可以这样验证,最后得出的D森林如下所示:(执行到Link(6, 5)时,当然如果继续往下执行的话,权值又会变化,因为路径会继续压缩)
比如说6节点,因为6节点在原森林的深度为3,而从图中可以看出6的权值+9的权值+2的权值=3+-7+7 = 3因此,是正确的,同理,可以验证其他节点的情况。
五、“编”后感
算法侧重于时间和空间,该程序主要时间花费是在find_depth 和link ,各自的时间复杂度都为O(n*G(n)),另外就是验证程序,只需要验证程序的权值累加起来是否等于原森林的深度即可。要注意一点的是压缩后的权值和没有压缩后的权值是不一样的。
全部代码下载:http://download.csdn.net/source/2936858
- Find_Depth和Link的实现
- LINK 2005 和 LINK 1169 的解决办法
- LINK 2005 和 LINK 1169 的解决办法
- LINK 2005 和 LINK 1169 的解决办法
- LINK 2005 和 LINK 1169 的解决办法
- 可变Link颜色的Link控件的实现
- @import 和 link 的区别
- link和domain的区别
- @import和link的区别
- link和domain的区别
- link和@import的区别
- link和@import的区别
- link和domain的区别
- @import和link的区别
- link和@import的区别
- link和@import的区别
- link和domain的区别
- link和@import的区别
- Java培训笔记22--自学异常类
- 少走弯路的十条忠告
- 我就是一textbox
- how to implement it using Error.pm(转)
- Poj 1258
- Find_Depth和Link的实现
- 变量的内存分配和释放
- 圣诞节
- perl 特殊变量(转)
- STL_Algorithm5-math: random_shuffle, count, count_if, min_element, max_element, accumulate, for_each, transform
- onstat -k相關解釋
- 求指点 程序员的出路!!
- 使用gsoap实现一个简单的 QQ在线状态查询程序
- android SDK2.3 更新改动翻译