代码改变世界

算法导论-用于不相交集合的数据结构

2012-05-15 11:33 by meteorgan, 895 阅读, 0 推荐, 收藏, 编辑
摘要:21.2-4 对于图21-3中操作序列的运行时间,给出其紧确的渐近界。假定采用的是链表表示和加权合并启发式策略。 解:make-set,O(n);加权合并启发,每次将较短链表链接到较长链表,即每次将长度为1的集合链接到另外的链表上,时间O(n)。总时间O(n)。21.2-5 当采用链表表示时,给出对UNION的一个简单的改动,使得无需让tail指针指向每个链表中的最后一个对象。无论是否采用了加权合并启发式策略,你所做的修改不应改变UNION过程的渐进运行时间。 解:设合并的链表为A, B,将B链接到A上。可以将A的第一个元素指向下一个元素的指针指向head[B],然后遍历B,更改B中元素指.. 阅读全文

算法导论-概率分析和随机算法习题解

2012-05-04 11:54 by meteorgan, 2361 阅读, 0 推荐, 收藏, 编辑
摘要:5.1-3 假设你希望以各1/2的概率输出0和1。你可以自由使用一个输出0或1的过程BIASED-RANDOM。它以概率p输出1,以概率1-p输出0,其中0 < p < 1,但是你并不知道p的值。给出一个利用BIASED-RANDOM作为子程序的算法,返回一个无偏向的结果,即以概率1/2返回0,以概率1/2返回1。作为p的函数,你的算法的期望运行时间是多少? 解:代码:1 while true:2 x = BIASED-RANDOM()3 y = BIASED-RANDOM()4 if x != y:5 return xx != y 存在两种情况,x... 阅读全文

算法导论-平摊分析习题解

2012-05-02 10:25 by meteorgan, 2504 阅读, 1 推荐, 收藏, 编辑
摘要:17.2-3 假设我们希望不仅能使一个计数器增值,也能使之复位至零(即,使其中所有的位都为0)。请说明如何将一个计数器实现为一个位数组,使得对一个初始为零的计数器,任一个包含n个INCREMENT和RESET操作的序列的时间都为O(n)。(提示:保持一个指针指向高位1) 解:如提示所言,保存一个指针指向高位1。规定把某一位设为1的操作收取4元的平摊费用,其中1元用来支付置位操作的实际代价,剩余3元作为存款。维护指针花费1元,当将该位翻转为0时,花费其中1元,置位花费1元。所以n个操作的序列时间至多为4n = O(n)。17.3-7 设计一个数据结构来支持整数动态多重集合S上的下列两个操作: . 阅读全文

算法导论-数据结构的扩张习题解

2012-04-29 09:23 by meteorgan, 485 阅读, 0 推荐, 收藏, 编辑
摘要:14.1-7 说明如何在O(nlgn)的时间内,利用顺序统计树对大小为n的数组中的逆序对进行计数。 解:j的逆序对为[1, j]区间内大于j的元素的个数,这个个数与j的秩有关,且值为j - r[j],这个值可以在O(lgn)时间内取得。故所有的数的逆序对可以在O(nlgn)时间内取得。14.1-8 现有一个圆上的n条弦,每条弦都是按其端点来定义的。请给出一个能够在O(nlgn)时间内确定圆内相交弦的对数(例如,如果n条弦都是直径,它们相交与圆心,则正确的答案为C2n)。假设任意两条弦都不会贡献端点。 解:1. 逆时针顺序给每条弦的端点赋值,大小顺序为[1, 2n]。 2. 给每条弦标... 阅读全文

算法导论-红黑树习题解

2012-04-27 15:02 by meteorgan, 872 阅读, 0 推荐, 收藏, 编辑
摘要:13.2-4 证明:任何一棵含n个节点的二叉查找树,可以通过O(n)次旋转,转变成另一棵含n个节点的二叉查找树。 解:1. 任意一棵含n个节点的二叉查找树可以通过至多n-1次右旋操作变成一棵仅有右孩子的单链树(这可以通过对每个有左孩子的节点进行右旋来完成)。 2. 可以通过1中的反向操作将一个仅有右孩子的单链树变成一棵二叉查找树。 3. 通过步骤1, 2可以在2n-2步内将任意一棵含n个节点的二叉查找树转变成一棵含n个节点的二叉查找树。13.3-6 说明如果红黑树的表示中不提供父指针的话,应当如何有效的实现RB-INSERT。 解:方法比较笨……如果不提供父指针的话,为旋转造成... 阅读全文

算法导论-散列表习题解

2012-04-24 10:12 by meteorgan, 1432 阅读, 0 推荐, 收藏, 编辑
摘要:11.1-4 我们希望通过利用在一个非常大的数组上直接寻址的方式来实现字典。开始时,该数组中可能存在废料,但要对整数数组进行初始化是不现实的,因为该数组规模太大。请给出在大数组上实现直接寻址字典的方案。每个存储的对象占用O(1)的空间;操作SEARCH, INSERT,DELETE的时间为O(1);对数据结构的初始化的时间为O(1)。 解: 由于数组中存在废料,直接对字典进行查询可能取到非法的值。因此需要对字典中的关键字进行验证。方法是:用数组实现一个栈S,栈顶部为TOP[S]栈大小等于已插入到词典中的关键字的个数,如果关键字k的确存在,则令D[k] = j(D是用原数组实现的字典),S[j. 阅读全文

算法导论-贪心算法习题解

2012-04-22 08:56 by meteorgan, 1926 阅读, 0 推荐, 收藏, 编辑
摘要:16.2-6 说明如何在O(n)时间内解决部分背包问题。 解:先求avgi = vi/wi,如果按照avgi从大到小排序,再贪心选择的话,时间复杂度为O(nlgn),当然可以采用非比较的排序算法达到O(n)的时间复杂度。更一般的情况,不需要排序,例如:如果a1, a2,a3是avgi 最大的三个物品,如果它们的总量和不大于W,我们是不需要知道它们间的相对顺序的。于是有以下算法:找avg 的中位数m,将avg 分为三个集合G = {ai: avgi < m}, Q = {ai: avgi = m}, P = {ai: avgi > m}。分别对G, Q, P中元素求和得SG, SQ, 阅读全文

算法导论-每对顶点间的最短路径习题解

2012-04-13 12:02 by meteorgan, 1043 阅读, 0 推荐, 收藏, 编辑
摘要:25.1-10 写出一个有效的算法来计算图中最短路径的负权回路的长度(即所包含的边数)。 解:在SLOW-ALL-PAIR-SHORTEST-PATHS()计算L(m)的过程中,第一次发现有对角元素小于0,则该m为所求的长度。如果m=n+1是仍未有主元元素的值小于0,则图中没有负权回路。时间复杂度为O(n4)。25.2-9 假定一个有向无环图的传递闭包可以在f(|V|,|E|)时间内计算,其中f是|V|和|E|的单调递增函数。证明:计算一般有向图G=(V,E)的传递闭包G*=(V,E)的时间为f=(|V|,|E|)+O(V+E*)。 解:1. 计算图G的强连通分支。时间O(V+E)。 ... 阅读全文

算法导论-单源最短路径习题解

2012-04-11 09:32 by meteorgan, 2593 阅读, 0 推荐, 收藏, 编辑
摘要:24.1-5 设G=(V,E)为一带权有向图,其权函数w: E->R。请给出一个O(VE)时间的算法,对于每个顶点v 属于V,找出值δ*(v) = min{δ(u,v)},u属于V。 解:1. 对每个顶点,令d[v] = 0。(初始情况,如果没有负权边,则δ*(v) = 0) 2. 用Bellman-ford算法,计算d[v],得d[v] =δ*(v)。 简单证明:设δi(u,v)为从u到v边个数不超过i的路径的最小值。δ*i (v) = min{δi(u,v)},u属于V。则有δ*(v) =δ*n-1(v)。可以数学归纳法证明d[v] <=δ*i(v)。显然d[v] <=δ 阅读全文

算法导论-最小生成树习题解

2012-04-04 11:57 by meteorgan, 2946 阅读, 0 推荐, 收藏, 编辑
摘要:23.1-11 给定一个图G和一棵最小生成树T,假定减小了不在T中的某条边的权值。请给出一个算法,来寻找经过修改的图中的最小生成树。 解:将这条修改了权值的边加入到T中,则T中形成环,找到这个环,然后删除环中权值最大的边。 23.2-4 假设在某个图中,所有的边的权值都一致分布在半开区间[1, 0)之间。对于Kruskal 和Prim这两个算法,你可以让哪一个运行得更快些? 解:可以让Kruskal 算法运行的更快些。由于权值均匀分布在[1,0)区间内,可以使用桶排序排序权值。这样Kruskal算法的时间复杂度为O(|E|a(|V|))。 ps: 顺便说下Kruskal和Prim... 阅读全文