收藏 分享(赏)

中科院计算机算法设计与分析各章作业+历年习题.pdf

上传人:weiwoduzun 文档编号:4018873 上传时间:2018-12-05 格式:PDF 页数:77 大小:1.81MB
下载 相关 举报
中科院计算机算法设计与分析各章作业+历年习题.pdf_第1页
第1页 / 共77页
中科院计算机算法设计与分析各章作业+历年习题.pdf_第2页
第2页 / 共77页
中科院计算机算法设计与分析各章作业+历年习题.pdf_第3页
第3页 / 共77页
中科院计算机算法设计与分析各章作业+历年习题.pdf_第4页
第4页 / 共77页
中科院计算机算法设计与分析各章作业+历年习题.pdf_第5页
第5页 / 共77页
点击查看更多>>
资源描述

1、 1 中国科学院大学历年习题 习题一 复杂性分析初步 1. 试确定下述程序的执行步数,该函数实现一个 m n 矩阵与一个 n p 矩阵之间的乘法: 矩阵乘法运算 template void Mult(T *a, T *b, int m, int n, int p) /m n 矩阵 a 与 n p 矩阵 b 相成 得到 m p 矩阵 c for(int i=0; i void Mult(T *a, T *b, int m, int n, int p) 0 0 0 for(int i=0; i bool MinMax(T a, int n, int if(aMax bool MinMax(T a,

2、 int n, int else if(aMax=(2n)/2=n,而一个含有 n个顶点的树有 n-1条边 。因 m=nn-1, 故该图一定含有圈 。 (定义: 迹 是指边 不重复的途径,而顶点不重复的途径称为 路 。起点和终点重合的途径称为闭途径,起点和终点重合的迹称为闭迹,顶点不重复的闭迹称为 圈 。) 2)证明: 设有向图最长的有向迹 ,10 kVVVP 每个顶点出度大于等于 1,故存在 V 为 kV 的出度连接 点, 使得 VVk 成为一条有向边,若 , PV 则得到比 P 更长的有向迹,与 P矛盾,因此必有 PV ,从而该图一定含有有向圈。 2.设 D是至少有三个顶点的连通有向图。如

3、果 D中包含有向的 Euler环游(即是通过 D 中每条有向边恰好一次的闭迹),则 D 中每一顶点的出度和入度相等。反之,如果 D中每一顶点的出度与入度都相等,则 D一定包含有向的 Euler 环游。这两个结论是正确的吗?请说明理由。如果 G 是至少有三个顶点的无向图,则 G包含 Euler环游的条件是什么? 证明: 1)若图 D 中包含有向 Euler 环游, 下证明 每个顶点的入度和出度相等。 如果该有 向图含有 Euler 环游,那么该环游必经过每个顶点至少一次,每经过一次,必为“进”一次接着“出”一次,从而入 度等于出度。从而,对于任意顶点,不管该环游经过该顶点多少次,必有 入度等于出

4、度。 2)若图 D 中每个顶点的入度和出度相等,则该图 D 包含 Euler 环游。证明如下。 7 对顶点个数进行归纳。 当顶点数 |v(D)|=2 时,因为每个点的入度和出度相等,易得构成有向 Euler环游。 假设顶点数 |v(D)|=k 时结论成立,则 当顶点数 |v(D)|=k + 1 时,任取 v v(D).设 S=以 v 为终点的边 , K=以 v为始点的 边 ,因为 v 的入度和出度相等,故 S 和 K 中边数相等。记 G=D-v.对 G做如下操作 : 任取 S 和 K 中各一条边 21 ee、 ,设在 D 中 vve 11 , 22 vve ,则对 G 和 S做如下操作 21v

5、vGG , 2eSS ,重复此步骤直到 S 为空。这个过程最终得到的 G 有 k 个顶点,且每个顶点的度与在 G 中完全一样。由归纳假设, G 中存在有向 Euler 环游,设为 C。在 G 中从任一点出发沿 C 的对应边前行,每当遇到上述添加边 v1v2 时,都用对应的两条边 e1, e2 代替,这样可以获得有向 Euler环游。 3) G 是至少有三个顶点的无向图,则 G 包含 Euler 环游等价于 G 中无奇度顶点。(即任意顶点的度为偶数)。 3设 G是具有 n个顶点和 m条边的无向图,如果 G是连通的,而且满足 m = n-1,证明 G是树。 证明:思路一: 只需证明 G 中无圈。

6、若 G 中有圈,则删去圈上任一条边 G 仍连通。而每个连通图边数 e=n(顶点数 ) 1, 但删去一条边后 G 中只有 n-2 条边 ,此时不连通 , 从而 矛盾,故 G 中无 圈,所以 G 为树。 思路二: 当 2n 时, 112 m ,两个顶点一条边且连通无环路,显然是树。 设当 )2,(1 kNkkn 时,命题成立, 则 当 kn 时,因为 G 连通且无环路,所以至少存在一个顶点 1V ,他的度数为 1,设该顶点所关联的边为 ).,( 211 VVe 那么去掉顶点 1V 和 1e ,便得到了一个有 k-1 个顶点的连通无向无环路的子图 G ,且 G 的边数 1 mm ,顶点数 1 nn

7、。由8 于 m=n-1,所以 11)1(1 nnmm ,由归纳假设知, G 是树。 由于 G 相当于在 G 中为 2V 添加了一个子节点,所以 G也是树。 由( 1),( 2)原命题得证。 4. 假设用一个 nn 的数组来描述一个有向图的 nn 邻接矩阵,完成下面工作: 1) 编写一个函数以确定顶点的出度,函数的复杂性应为 );(n : 2) 编写一个函数以确定图中边的数目,函数的复杂性应为 );( 2n 3) 编写 一个函数删除边 ),( ji ,并确定代码的复杂性。 解答:( 1)邻接矩阵表示为 nna ,待确定的顶点为第 m 个顶点 mv int CountVout(int *a,int

8、 n,int m) int out = 0; for(int i=0;iB-E|0 B-A-C|0 C-B-D-E|0 D-C|0 E-A-C-F-G|0 F-E-G|0 G-E-F|0 解:初始化 数组 DFN:=0, num=1; A 为树的根节点 ,对 A 计算 DFNL(A,null), DFN(A): =num=1; L(A): =num=1; num:=1+1=2。 从邻接链表查到 A 的邻接点 B, 因为 DFN(B)=0,对 B 计算 DFNL(B,A) DFN(B): = num=2; L(B): =num=2; num: =2+1=3。 查邻接链表得到 B 的邻接点 A,因

9、为 DFN(A)=10, 但 A=A,即是 B 的父节点,无操作。 接着查找邻接链表得到 B 的邻接点 C, 因为 DFN(C)=0,对 C 计算 DFNL(C,B) DFN(C): = num=3; L(C): =num=3; num:=3+1=4。 查 找 C 的邻接点 B,因为 DFN(B)=10, 但 B=B,即是 C 的父节点,无操作。 接着查找邻接链表得到 C 的邻接点 D, 因为 DFN(D)=0,对 D 计算 DFNL(D,C), DFN(D): = num=4; L(D): =num=4; num:=4+1=5。 一个无向图 G A B E D G C F 1 1 2 3 4

10、 7 5 6 1 1 1 5 5 4 11 查找得 D 邻接点 C,而 DFN(C)=3 0,但 C=C,为 D的父节点, L(D)保持不变。 D的邻接链表结束, DFNL(D,C)的计算结束。 返回到 D 的父节点 C, 查找邻接链表得到 C 的邻接点 E, 因为 DFN(E)=0,对 E 计算 DFNL(E,C), DFN(E): =num=5; L(E): =num=5; num:5+1=6; 查找得 E 邻接点 A,因 DFN(A)=1 0,又 A C,变换 L(E)=min(L(E),DFN(A)=1。 查找得 E 邻接点 C,因 DFN(C)=3 0,但 C=C,无操作。 查找得

11、E 邻接点 F,因 DFN(F)=0, 对 F 计算 DFNL(F,E), DFN(F): =num=6; L(F): =num=6; num:=6+1=7; 查找得 F 邻接点 E,因 DFN(E)=5 0,但 E=E,无操作。 查找得 F邻接点 G,因 DFN(G)=0, 对 G 计算 DFNL(G,F), DFN(G): =num=7; L(G): =num=7; num=7+1=8; 查找 G 邻接点 E,因 DFN(E)=5 0,又 E F, L(G)=min(L(G),DFN(E)=5 查找得 G邻接点 F,因 DFN(F)=6 0,但 F=F,无操作。 G的邻接链表结束, DFN

12、L(G,F)的计算结束。 L(F): =min(L(F), L(G)=min(6,5)=5 F 的邻接链表结束, DFNL(F,E)的计算结束。 L(E):=min(L(E),L(F)=min(1,5)=1 E 邻接链表结束, DFNL(E,C)计算结束。 L(C):=min(L(C),L(E)=min(3,1)=1 C 的邻接链表结束, DFNL(C,B)计算结束。 L(B):=min(L(B),L(C)=min(2,1)=1 查找 B的邻接链表 结束, DFNL(B,A)计算结束。 L(A):=min(L(A),L(B)=1 查找得 A的邻接点 E,因 DFN(E)=0,又 E null,

13、则 L(A)=min(L(A),DFN(E)=1 查找 A 的邻接链表结束, DFNL(A,null)计算结束。 最终结果为:深索数 DFN,与最低深索数 L 如下 DFN(A)=1, DFN(B)=2, DFN(C)=3, DFN(D)=4, DFN(E)=5, DFN(F)=6, DFN(G)=7 12 L(A)=1; L(B)=1; L(C)=1; L(D)=4; L(E)=1; L(F)=5;L(G)=5. 序 节点 DFN L 栈顶 栈底 2-连通 割点 1 A 1 (1,0,0,0,0,0,0) (A,B) 2 B 2 (1,2,0,0,0,0,0) (B,C),(A,B) 3 C

14、 3 (1,2,3,0,0,0,0) (C,D),(B,C),(A,B) 4 D 4 (1,2,3,4,0,0,0) (B,C),(A,B) (C,D); C 5 E 5 (1,1,1,4,1,0,0) (E,F),(E,A),(B,C),(A,B) 6 F 6 (1,1,1,4,1,6,0) (F,G), (E,F),(E,A),(B,C),(A,B) 7 G 7 (1,1,1,4,1,5,5) (E,A),(B,C),(A,B) (G,E),(F,G), (E,F) E 8 (1,1,1,4,1,5,5) (E,A),(B,C),(A,B) 附课本讲义 程序 2-3-1 对图 2-3-5

15、的执行过程 开始 DFNL(A,*) DFN(A):=1; L(A):=1; num:=2; DFN(B)=0, DFNL(B,A) DFN(B):=2; L(B):=2; num:=3; DFN(A)=10, 但 A=A, 不做任何事情 DFN(C)=0, DFNL(C,B) DFN(C):=3; L(C):=3; num:=4; DFN(B)=20, 但 B=B, 不做任何事情 DFN(D)=0, DFNL(D,C) DFN(D):=4; L(D):=4 DFN( C); num:=5; 弹出( C,D)边 DFN(C)=30, 但 C=C, 不做任何事情 DFN(E)=0, DFNL(E

16、,C) DFN(E):=5; L(E):=5 DFN( C); num:=6; 弹出( C,E)边 A B B B A C B B C B A D C B B C B A E C B B C B A F C B B F C B A A F C B B 13 DFN(C)=30, 但 C=C, DFN(F)=0, DFNL(F,C) DFN(F):=6; L(F):=6; num:=7; DFN(A)=10, AC, L(F):=min6,1=1; DFN(C)=30, 但 C=C, DFN(G)=0, DFNL(G,F) DFN(G):=7; L(G):=7; num:=8; DFN(F)=6

17、0, 但 F=F, DFN(H)=0, DFNL(H,G) DFN(H):=8; L(H):=8 DFN(G); num:=9; 弹出( G,H)边 DFN(G)=70, 但 G=G, DFN(I)=0, DFNL(I,G) DFN(I):=9; L(I):=9; num:=10; DFN(F)=60, FG, L(I):=min9,6=6; DFN(G)=70, 但 G=G, DFN(J)=0, DFNL(J,I) DFN(J):=10; L(J):=10; num:=11; DFN(F)=60, FI, L(J):=min10,6=6; DFN(G)=70, GI, L(J):=min6,

18、7=6; DFN(I)=90, 但 I=I, L(I):=min6,6=6; L(G):=min7,6=6 DFN(F) 弹出 (J,G), (J,F), (I,J), (I,F), (G,I), (F,G) 边 L(F):=min1,6=1; L(C ):=min3,1=1; L(B):=min2,1=1 DFN(A) 弹出 (F,A), (C,F), F F C B A G A F C B B G F F C B A H G A F C B B G F F C B A I G A F C B B I G F F C B A F I G A F C B B I I G F F C B A J

19、 F I G A F C B B J I I G F F C B A F J F I G A F C B B J J I I G F F C B A G F J F I G A F C B B 14 (B,C), (A,B) 边 7 对图的另一种检索方法是 D-Search。该方法与 BFS 的不同之处在于将队列换成栈,即下一个要检测的结点是最新加到未检测结点表的那个结点。 1)写一个 D-Search算法; 2)证明由结点 v开始的 D-Search能够访问 v可到达的所有结点; 3)你的算法的时、空复杂度是什么? 解: 1)同第 5 题, proc DBFS(v) /宽度优先搜索 G,从顶

20、点 v 开始执行,数组 visited 标示各 /顶点被访问的序数;数组 s 将用来标示各顶点是否曾被放进待检查队 /列,是则过标记为 1,否则标记为 0;计数器 count 计数到目前为止已 /经被访问的顶点个数,其初始化为在 v 之前已经被访问的顶点个数 PushS(v , S);/ 将 S 初始化为只含有一个元素 v 的栈 while S 非空 do u:= PullHead(S); count:=count+1; visitedu:=count; for 邻接于 u 的所有顶点 w do if sw=0 then PushS(w , S); /将 w 压入栈中 sw:=1; endif

21、 endfor endwhile endDBFS 图的 D 搜索算法伪代码: proc DBFT(G, ) /count、 s 同 DBFS 中的说明, branch 是统计图 G 的连通分支数 count:=0; branch:=0; for i to n do si:=0; /将所有的顶点标记为未被访问 endfor for i to do if si=0 then DBFS(i); branch:=branch+1; 15 endif endfor endDBFT 2)证明: 除结点 v 外,只有当结点 w 满足 sw=0 时才被 压入栈中 ,因此每个结点至多有一次被 压入栈中,搜索 不

22、会出现重叠和死循环现象 ,对于每一个 v 可到达的节点,要么直接被访问,要么被压入栈中,只有栈内节点全部弹出被访问后,搜索才会结束,所以 由结点 v开始的 D-Search 能够访问 v 可到达的所有结点 。 3) :除结点 v 外,只有当结点 w 满足 sw=0 时才被压入栈中,因此每个结点至多有一次被压入栈中。需要的 栈 空间至多是 -1; visited 数组变量所需要的 空间为;其余变量所用的空间为 O(1),所以 s( ,)= ( )。 如果使用邻接链表, for 循环要做 d(u)次,而 while 循环需要做次,又 visited、 s 和 count的赋值都需要次操作,因而 t

23、( , )= ( + )。 如果采用邻接矩阵,则 while 循环总共需要做 2次操作, visited、 s 和 count 的赋值都需要次操作,因而 t( , )= ( 2)。 8.考虑下面这棵假想的对策树: 解: 2 )20 6 4 20 5 4 8 15 6 20 30 5 50 8 4 15 20 5 10 30 5 9 20 50 18 6 15 10 5 5 20 1)使用最大最小方法 (2-4-2)式获取各结点的值 max max max min min 16 2)弈者 A为获胜应该什么棋着? 20 6 4 20 5 4 8 15 6 20 30 5 50 8 4 15 20

24、5 10 30 5 9 20 50 18 6 15 10 5 5 20 X X1 X2 X3 X4 X1.1 X1.2 X2.1 X2.2 X3.1 X3.2 X4.1 X4.2 X1.1.1 X1.1.2 X1.1.3 X1.2.1 X2.1.1 X2.2.1 X3.1.1 X3.1.2 X1.1.1.1 X3.1.2.1 X3.2.1 X3.2.2 X3.2.3 X4.1.1 X4.2.1 X4.4.2 X4.2.3 X4.2.4 17 18 第三章 分治算法习题 1、编写程序实现归并算法和快速排序算法 参见后附程序 2、用长为 100、 200、 300、 400、 500、 600、

25、700、 800、 900、 1000 的 10 个数组的排列来统计这两种算法的时间复杂性。 有些同学用的微 秒 us 用 s 可能需要把上面的长度改为 10000, 100000,都可以 大部分的结果是快速排序算法要比归并算法 快一些。 3、讨论归并排序算法的空间复杂性。 解析:归并排序由分解与合并两部分组成,如果用 ()Sn表示归并排序所用的空间。 则由 MergeSort(low, mid) /将第一子数组排序 )2/(nS MergeSort(mid+1, high) /将第二子数组排序 )2/(nS Merge(low, mid, high) /归并两个已经排序的子数组 nnO 2)

26、( 则 )(),2/(m a x)( nOnSnS )()2/()( nOnSnS 递归推导得 )()2()1()()2()2()2()1()()2()4()()2()(1nOnOSnOnOnOnOSnOnOnSnOnSnSkk 又由存储数组长度为 n ,则有 )()( nOnS 因此,空间复杂度为 )(nO 。 4、说明算法 PartSelect 的时间复杂性为 ()On 证明:提示:假定数组中的元素各不相同,且第一次划分时划分元素 v 是第 i 小元素的概率为 n/1 。因为 Partition 中的 case 语句所要求的时间都是 )(nO ,所以,存在常数 c ,使得算法 PartSe

27、lect 的平均时间复杂度 )(nCkA 可以表示为 19 )1()(1)( 1 ki nik kAikAkA iCinCncnnC 令 ),(m ax)( nCnR kAk取 ),1(RC 试证明 cnnR 4)( 。 证明:令 )(nCkA 表示 n 个元素的数组 A 中寻找第 k 小元素的平均时间复杂度,因1)-n0,Partition( 的时间复杂度是 )(nO ,故存在常数 c,使得算法 PartSelect 的平均时间复杂度 )(nCkA 可以表示为 )1()(1)(1 ki nikkAikAkA iCinCncnnC 令 ),(m ax)( nCnR kAk且不妨设 等式在 nk

28、k 时成立,则 )(nR 满足 )1()(1)( 1 ki nik kAikA iCinCncnnR 以下用第二数学归纳法证明 cnnR 4)( 。取 ),1(RC 当 1n 时,取 c C/4,则 cR 4)1( 当 2n 时, cccRcR 44212)1(212)2( 成立。 对于一般的 n,设对所有小于 n 的自然数 cnnR 4)( 成立,则 cnnccnnnnccnnnnnccnnnknknccnnkknknknccnnkknnnccnnRkRkRknRnRncnnRnnnnnnnnnnn4)33(143)23)21(4)23)1(4)2)1)(2)2)(1(4)1()1()1(4

29、)1()1()()1()1(1)(22222得证。 证明:( 1)当 7r 时,假设数组 A 中元素互不相同。由于每个具有 7 个元素的数组的中间值 u 是该数组中的第 4 小元素,因此数组中至少有 4 个元素不大于 u, /7n个中间值中20 至少有 /7 / 2n个不大于这 些中间值的中间值 v。因此,在数组 A 中至少有 4 / 7 / 2 2 / 7nn 个元素不大于 v。换句话说, A 中至多有 5 1 22 / 7 2 ( / 7 / 7) , (0 6 )77n n n n e n e 个元素大于 v。同理,至多有 5 1277n 个元素小于 v。这样,以 v 为划分元素,产生的

30、新数组至多有 5 1277n 个元素。当 24n 时, 5 12 117 7 14nn 。 另一 方面,在整个执行过程中,递归调用 Select 函数一次,涉及规模为 /7n ,而下一次循环 Loop 涉及的数组规模为 1114n 。程序中其他执行步的时间复杂度至多是 n 的倍数 cn ,用()Tn表示算法在数组长度为 n 的时间复杂度,则当 24n 时,有递归关系 1 1 1( ) ( ) ( )7 1 4T n T n T n c n 用数学归纳法可以证明, ( ) 14T n cn 。所以时间复杂度是 ()On 。 ( 2)当 3r 时,使用上述方法进行分析,可知在进行划分后数组 A 中

31、有至多 nn 653232 个元素。而递归关系为 cnnTnTnT )65()31()( 。若通过归纳法证明出有 ()T n kcn 的形式,用数学归纳法可以证明, cnnT 28)( 。所以时间复杂度是 ()On 。 归并排序的 C+语言描述 #include templatevoid MergeSort(T a,int left,int right); templatevoid Merge(T c,T d, int l,int m,int r); templatevoid Copy(T a,T b,int l,int r); void main() int const n(5); int

32、an; coutai; /for(int j=0;j void MergeSort(T a,int left,int right) / if(left void Merge(T c,T d,int l,int m,int r) int i=l; int j=m+1; int k=l; while(im) for(int q=j;q void Copy(T a,T b, int l,int r) for(int i=l;i templatevoid QuickSort(T a,int p,int r); templateint Partition(T a,int p,int r); void m

33、ain() int const n(5); int an; coutai; QuickSort(a,0,n-1); cout void QuickSort(T a,int p,int r) if(p int Partition(T a,int p,int r) int i=p,j=r+1; T x=ap; while(true) while(a+ix); if(i=j)break; Swap(ai,aj); ap=aj; aj=x; return j; 23 template inline void Swap(T s=t; t=temp; 第四章作业 部分参考答案 1 设有 n 个顾客同时等待

34、一项服务。顾客 i 需要的服务时间为 niti 1, 。应该如何安排 n 个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是各顾客等待服务的时间的总和。试给出你的做法的理由(证明)。 策略 : 对 1it i n 进行排序, ,21 niii ttt 然后按照递增顺序 依次服务 12, ,., ni i i即可 。 解析: 设 得 到 服 务 的 顾 客 的 顺 序 为 12, ,., nj j j , 则 总 等 待 时 间 为,2)2()1( 1221 nn jjjj tttntnT 则 在总等待时间 T 中 1jt 的权重最大, jnt的权重最小。故让所需时间少的顾客先得到服务可

35、以减少总等待时间。 证明: 设 ,21 niii ttt ,下证明当按照不减顺序依次服务时,为最优策略。 记按照 niii 21 次序服务 时,等待 时间为 T ,下证明任意互换两者的次序, T都不减。 即假设互换 ji, )( ji 两位顾客的次序,互换后等待总时间为 T ,则有. TT 由 于 ,2)2()1( 1221 nn iiii tttntnT ,2)()()2()1( 1221 nnji iiiiii tttjntintntnT ,2)()()2()1( 1221 nnij iiiiii tttjntintntnT 则有 .0)( ij ii ttijTT 24 同理可证其它次序

36、,都可以由 niii 21 经过有限次两两调换顺序后得到,而每次交换,总时间不减,从而 niii 21 为最优策略。 2 字符 ha 出现的频率分布恰好是前 8 个 Fibonacci 数,它们的 Huffman编码是什么?将结果推广到 n 个字符的频率分布恰好是前 n 个 Fibonacci 数的情形。 Fibonacci 数的定义为: 1,1,1 1210 nifFFFFF nnn 解:前 8 个数为 a, b, c, d, e, f, g, h 1, 1, 2, 3, 5, 8, 13, 21 Huffman 哈夫曼编码 树为: 所以 a 的编码为: 1111111 b 的编码为: 11

37、11110 c 的编码为: 111110 d 的编码为: 11110 54 h:21 33 20 12 7 4 2 g:13 f:8 e:5 d:3 C:2 b:1 a: 1 0 1 0 0 0 0 0 0 1 1 1 1 1 1 25 e 的编码为: 1110 f 的编码为: 110 g 的编码为: 10 h 的编码为: 0 推广到 n 个字符: 第 1 个字符: n-1 个 1, 1111n第 2 个字符: n-2 个 1, 1 个 0, 01112n第 3 个字符: n-3 个 1, 1 个 0, 01113n 第 n-1 个字符: 1 个 1 , 1 个 0, 10 第 n 个字符:

38、1 个 0 , 0 3 设 nppp , 21 是准备存放到长为 L 的磁带上的 n 个程序,程序 ip 需要的带长为 ia 。设 Lani i 1,要求选取一个能放在带上的程序的最大子集合(即其中含有最多个数的程序) Q 。构造 Q 的一种贪心策略是按 ia 的非降次序将程序计入集合。 1) 证明这一策略总能找到最大子集 Q ,使得 Qp ii La。 2) 设 Q 是使用上述贪心算法得到的子集合,磁带的利用率可以小到何种程度? 3) 试说明 1)中提到的设计策略不一定得到使 Qp ii La/取最大值的子集合。 1) 证明: 不妨 设 12. na a a , 若该贪心策略构造的子集合 Q

39、 为 , 21 saaa ,则 s 满足 si sssi i LaaLa 1 11 、。 要证明能找到最大子集,只需说明 s 为可包含的最多程序段数即可。 即证不存在多于 s 个的程序集合 )(,21 skaaaQ kiii ,使得 Qp ii La。 反证法,假设存在多于 s 个的程序集 )(,21 skaaaQ kiii ,满足 kj i Laj1。 26 因为 12. na a a 非降序排列,则 Laaaaaaakiiiks 2121。 因为 sk 且为整数,则其前 s+1 项满足 Laaaa ss 121 。 这与贪心策略构造的子集和 Q 中 s 满足的 si ss Laa1 1矛盾

40、。故假设不成立,得证。 2)磁带的利用率为 Qp ii La /;(甚至最小可为 0,此时任意 Lai 或者 Qp ii La) 3)按照 1)的策略可以使磁带上的程序数量最多,但程序的总长度不一定是最大的,假设 , 21 iaaa 为 Q 的最大子集, 但是 若 用 1ia 代替 ia ,仍满足 11 1ik ik Laa ,则 , 1121 ii aaaa 为总长度更优子集。 4.同学们的几种不同答案 构造哈夫曼树 思想 ,将所有的节 点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。这样,新节点就是两个被替换节点的父节点了。如此循环,直到队列中只剩

41、一个节点(树根)。 答案 1) 伪代码: typedef struct unsigned int weight; unsigned int parent, lchild, rchild; HTNode, * HuffmanTree; typedef char * HuffmanCode; proc HuffmanCoding(HuffmanTree #define infinite 50000 /定 义 Huffman 树和 Huffman 编码的存储表示 typedef struct unsigned int weight; /字符的频数 unsigned int parent, lchil

42、d, rchild; /双亲结点,左孩子,右孩 子 HTNode, * HuffmanTree; typedef char * HuffmanCode; void Select(HuffmanTree HT, int n, int 28 void HuffmanCoding(HuffmanTree void main() int i, n, *w; cout n; cout wi; HuffmanTree HT; HuffmanCode HC; HuffmanCoding(HT, HC, w+1, n); cout HTi.weight) s2 = i; else if (HTi.parent

43、 = 0 29 /构造 Huffman 树 HT, 并求出 n 个字符的 Huffman 编码 HC void HuffmanCoding(HuffmanTree /haffman 编码 typedef struct int weight;/权值 int parent;/父节节点 int LChild;/左子节点 int RChild;/右子节点 HTNode,HuffmanM+1;/huffman 树 typedef struct Node int weight; /叶子结 点的权值 char c; /叶子结点 int num; /叶子结点的二进制码的长度 WNode,WeightNodeN; /*产生叶子结点的字符和权值 */ void CreateWeight(char ch,int *s,WeightNode CW,int *p) int i,j,k; int tag; *p=0;/叶子节点个数 /统计字符出现个数 ,放入 CW for(i=0;chi!=0;i+) tag=1; for(j=0;ji;j+)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 网络科技 > 计算机原理

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报