算法导论
试着写写课后答案
默默可书虫
这个作者很懒,什么都没留下…
展开
-
<算法导论>练习10.2
10.2-1插入可以在常量的时间内完成,只需要将其插入到特定的位置比如链表的开始或结尾即可。删除元素需要找到要删除元素的位置,无法在常量的时间内完成,除非删除的元素在链表的开始或结尾。10.2-2栈的特点是先进后出以链表来模拟的话,插入删除操作均在链表头完成即可。代码如下:def push(l,x): x.next=l.head l.head=xdef pop(l): if l.head==None: return error else: x=l.head l.head=x原创 2021-05-23 20:50:01 · 95 阅读 · 0 评论 -
<算法导论>练习10.1
10.1-1push(s,4) s:4push(s,1) s:4,1push(s,3) s:4,1,3pop(s) s:4,1push(s,8) s:4,1,810.1-2第一个栈从数组的下标0开始向后增加,第二个栈从数组的末尾n-1开始向前增加。当两者的下标相遇时二者的总和为n,停止向栈中增加元素。10.1-3定义好判断队列满及空的函数,在每次插入以及删除的时候判断一下即可。判断函数如下:def queue_empty(Q): if Q.head==Q.tail:原创 2021-05-07 21:32:39 · 130 阅读 · 0 评论 -
<算法导论>练习9.2
9.2-1如果数组的长度是0,那么调用的randomized-select函数的第二个和第三个参数是相同的。如果调用发生在程序的第8行,即p=q-1,那么有k=q-p+1=0.而题目中的i表示要找数组中第i小的元素,那么i一定大于等于0,而程序进行到第8行的条件是i<k=0,不成立。同理可以证明如果是在第九行调用的话i会大于k,同样不成立,所以程序不会递归调用长度为空的数组。9.2-3def randomized_select(A,p,r,i): while true: if p==r原创 2021-05-07 14:42:03 · 227 阅读 · 0 评论 -
<算法导论>练习8.4
8.4-1B:1–0.13–0.162–0.203–0.394–0.425–0.536–0.647–0.71–0.798–0.8998.4-2如果所有的元素都放到了同一个桶中,那么桶排序就变成了插入排序(在书中的例子中,每个桶内部的排序方式是插入排序),如果他们恰好是按从大到小的顺序出现的,那么时间复杂度是O(n^2).提高效率的办法是在每个桶中使用堆排序或归并排序,不过这样的话要把链表转换为数组,需要额外的存储空间。...原创 2021-05-07 09:54:57 · 172 阅读 · 0 评论 -
<算法导论>练习8.2
8.2-2所谓稳定指的是相同元素的值在排序好的数列中的相对位置与他们在输入数组中的相对次序一样。从书中的代码中可以很清楚的得到这一结论,因为循环是从后向前进行迭代的,每次找到一个位置后会把c中的相应元素个数减一,所以再有相同的元素会插入到该元素的前面,保证相对位置不变。8.2-3该算法仍然是正确的,只是相同元素的相对位置反转了,它不再是稳定的了。8.2-4其实就是一道求前缀和的题,由书中计数排序代码的前九行可以计算出数组c,其中c[i]表示数组中小于等于i的元素个数,那么落在[a,…b]中的元素原创 2021-05-06 10:27:33 · 120 阅读 · 0 评论 -
<算法导论>思考7
7-2a.如果所有元素都相同,那么时间复杂度是O(n^2)b.def partition(A,p,r): x=A[p] low=p high=p for j in range(p+1,r): if A[j]<x: y=A[j] A[j]=A[high+1] A[high+1]=A[low] A[low]=y low=low+1 high=high+1 elif A[j]==x: swap(A[high+1],A[j]) # swap函数原创 2021-05-05 09:56:29 · 58 阅读 · 0 评论 -
<算法导论>练习7.3
7.3-1我们分析期望运行时间因为它代表的时间成本更加典型。7.3-2在最坏的情况下,调用random的次数是:T(n)=T(n−1)+1=nT(n)=T(n-1)+1=nT(n)=T(n−1)+1=n即Θ(n)\Theta(n)Θ(n).最好的情况也是Θ(n)\Theta(n)Θ(n)....原创 2021-05-03 12:19:50 · 118 阅读 · 0 评论 -
<算法导论>练习7.2
7.2-1证明方法和第二章的一样,这里不证了。7.2-2当元素都相同时,快速排序的时间复杂度是O(n^2),因为每次排序时没有大于所选的元素,所以相当于每次只排了一个元素。7.2-3按照书中所用的快排方式,时间复杂度是O(n^2),因为书中的代码取的分界元素是最后一个,若数组已经降序了 ,那么最后的元素一定是最小的,所以每次调用PARTITION只会排一个元素。7.2-4如上一题所说的那样,快排在几乎有序的数组中时间复杂度接近于n^2....原创 2021-05-03 12:08:59 · 165 阅读 · 0 评论 -
<算法导论>练习7.1
7.1-113,19,9,5,12,8,7,4,21,2,6,1113,19,9,5,12,8,7,4,21,2,6,1113,19,9,5,12,8,7,4,21,2,6,119,19,13,5,12,8,7,4,21,2,6,119,5,13,19,12,8,7,4,21,2,6,119,5,13,19,12,8,7,4,21,2,6,119,5,8,19,12,13,7,4,21,2,6,119,5,8,7,12,13,19,4,21,2,6,119,5,8,7,4,13,19,12原创 2021-04-30 09:24:21 · 81 阅读 · 0 评论 -
<算法导论>第六章思考
6-1a.不一样。当输入数据为1,2,3时,bulid_max_heap产生的堆为:3,2,1本题中给出的代码产生的数据为:3,1,2b.每次插入数据最多耗时O(lgn)O(lgn)O(lgn),一共要执行n次,总的复杂度为O(nlgn)O(nlgn)O(nlgn).6-2...原创 2021-04-28 18:50:29 · 127 阅读 · 0 评论 -
<算法导论>练习6.5
6.5-1将15与最后一个元素交换,并把堆的大小减1,类似于弹出操作,剩下的元素维持最大堆的性质,过程如下:1,13,9,5,12,8,7,4,0,6,213,1,9,5,12,8,7,4,0,6,213,12,9,5,1,8,7,4,0,6,213,12,9,5,6,8,7,4,0,1,26.5-2先在堆的末尾插入一个值为负无穷的节点,再调用heap-increase-key函数把该节点的值提高为要插入的值key。过程如下:15,13,9,5,12,8,7,4,0,6,2,1,-inf原创 2021-04-27 20:31:50 · 117 阅读 · 0 评论 -
<算法导论>练习6.4
6.4-1先把数组转化为最大堆,然后取出根节点,把剩余的节点数组再转化为最大堆,重复这个过程就是堆排序。5,13,2,25,7,17,20,8,45,13,20,25,7,17,2,8,45,25,20,13,7,17,2,8,425,5,20,13,7,17,2,8,425,13,20,5,7,17,2,8,425,13,20,8,7,17,2,5,44,13,20,8,7,17,2,5,2520,13,4,8,7,17,2,5,2520,13,17,8,7,4,2,5,255,13原创 2021-04-27 15:40:18 · 164 阅读 · 0 评论 -
<算法导论>练习6.3
6.3-15,3,17,10,84,19,6,22,95,3,17,22,84,19,6,10,95,3,19,22,84,17,6,10,95,84,19,22,3,17,6,10,984,5,19,22,3,17,6,10,984,22,19,5,3,17,6,10,984,22,19,10,3,17,6,5,96.3-2max-heap 维护堆的性质,比较 的是自己与左右孩子的关系,不会跨级比较。所以若最大值在底层,那么程序结束后它不会在A[1]的位置。...原创 2021-04-22 15:47:50 · 104 阅读 · 0 评论 -
<算法导论>练习6.2
6.2-127,17,3,16,13,10,1,5,7,12,4,8,9,027,17,10,16,13,3,1,5,7,12,4,8,9,027,17,10,16,13,9,1,5,7,12,4,8,3,06.2-2就是找到自身和左右孩子里最小的值交换即可。def min_heapify(A,i): l=left(i) r=right(i) if l<= A.heap_size and A[l] <A[i]: small=l else : small=i if r原创 2021-04-21 18:30:21 · 78 阅读 · 0 评论 -
<算法导论>练习6.1
6.1-1高度为h的堆最多有:1+2+22+...+2h1+2+2^2+...+2^h1+2+22+...+2h个元素。最少有1+2+22+...+2h−1+11+2+2^2+...+2^{h-1}+11+2+22+...+2h−1+16.1-2一个堆中的元素必定为2m+k−12^m+k-12m+k−1个,其中2^m个元素构成了一棵完全二叉树,剩下的k-1个元素构成了叶节点。所以堆的最大高度是m+1,也就是lgn向下取整,这里的lg是指以e为底的指数。6.1-3这其实就是大根堆的定义,构建大根堆原创 2021-04-15 20:59:28 · 119 阅读 · 0 评论 -
<算法导论>练习5.3
5.3-1把第一种情况单独列出来即可。5.3-2无法实现,这个题前面好像有,比如想由A[1,2,3]生成[3,2,1]是无法实现的,因为i是递增的,所以第一步只能和3交换得到[3,2,1],还会进行第二步的交换,生成[3,1,2].所以不能生成任意排列。5.3-3这种方法并不能产生均匀的随机排列。以n=3为例,for循环的每次迭代都会把第i个元素和第[1,2,3]之中的某个进行交换,所以第i次迭代会有3种不同情况。那么整个迭代经过排列组合一共会有33=273^3=2733=27种情况,而3个不同原创 2021-04-06 21:30:33 · 124 阅读 · 0 评论 -
<算法导论>练习5.2
5.2-1只雇用一次意味着能力最强者在第一个,概率是1n\frac1nn1.正好雇佣n次意味着所有人按能力大小顺序出现,一共有n!种情况,概率是1n!\frac1{n!}n!15.2-2要遍历所有人,其中第一个人一定会被雇佣,而且能力最大的人一定会被雇佣,则正好两次的情况就是雇佣第一个人以及能力最高的人,且他们之间所有人的能力要小于第一个人。概率为:p=∑i=1n−11n∑k=1iknp=\sum_{i=1}^{n-1} {\frac1n}\sum_{k=1}^{i} {\frac{k}{原创 2021-04-01 15:03:09 · 162 阅读 · 0 评论 -
<算法导论>练习5.1
5.1-2random(a,b)将返回一个介于(a,b)之间的整数,题目要求只能调用random(0,1),很明显要转变为二进制计算,且random(0,1)是已经实现了的,令k=⌈lg(b−a)⌉k=\left \lceil lg(b-a) \right \rceil k=⌈lg(b−a)⌉k代表了要生成序列的二进制位数,若生成的数不再(a,b)之间就重新生成。def random(a,b): l=b-a k=int(log(l,2)+1) res=0 for i in range(k原创 2021-04-01 09:46:43 · 126 阅读 · 0 评论 -
<算法导论>练习4.5
4.5-1判断一下分别属于哪种情况然后代入公式即可。a.Θ(nlog42)=Θ(n12)\Theta(n^{\log_42})=\Theta(n^\frac12)Θ(nlog42)=Θ(n21)b.Θ(nlog42lgn)=Θ(n12lgn)\Theta(n^{\log_42}lgn)=\Theta(n^\frac12lgn)Θ(nlog42lgn)=Θ(n21lgn)c.Θ(n)\Theta(n)Θ(n)d.Θ(n2)\Theta(n^2)Θ(n2)4.5-2题目描述的挺多,实际原创 2021-03-29 20:16:02 · 383 阅读 · 0 评论 -
<算法导论>练习4.3
4.3-1用数学归纳法证明即可,思路是假设n<=kn<=kn<=k时存在c使得T(k)<=cn2T(k)<=cn^2T(k)<=cn2成立,只要证明出n=k+1n=k+1n=k+1时,存在c使得T(k+1)<=c(k+1)2T(k+1)<=c(k+1)^2T(k+1)<=c(k+1)2。那么把T(k)和T(k−1)T(k)和T(k-1)T(k)和T(k−1)代入递归式得到:KaTeX parse error: Expected 'EOF', got原创 2021-03-29 15:20:15 · 751 阅读 · 2 评论 -
<算法导论>练习4.2
4.2-1就是代入书中的式子计算一下,令A=[1375]B=[6842]A=\begin{bmatrix} 1&3 \\ 7&5\end{bmatrix}B=\begin{bmatrix} 6&8 \\ 4&2\end{bmatrix}A=[1735]B=[6482]S1=B12−B22=8−2=6S_1=B_{12}-B_{22}=8-2=6S1=B12−B22=8−2=6同理,S2=4,S3=12,S4=-2,S5=6,原创 2021-03-26 20:28:08 · 264 阅读 · 0 评论 -
<算法导论>练习4.1
4.1-1所有元素都是负数时,最大子数组的和就是A中最大的元素。所有程序会返回A中最大的数。4.1-2两个for循环嵌套,且最大迭代次数是n,时间复杂度是Θ(n2)\Theta(n^2)Θ(n2)def find_maximum_subarray(a): n=len(a) max_sum=-float('inf') low=0;high=0 for i in range(n): sum_da=0 for j in range(i,n):原创 2021-03-25 19:46:03 · 215 阅读 · 2 评论 -
<算法导论>练习3.2
3.2-1因为f(m),与g(m)单调递增,所以,在n>m时有:f(m)<f(n)(1)g(m)<g(n)(2)f(m)<f(n)\quad(1)\\g(m)<g(n)\quad(2)f(m)<f(n)(1)g(m)<g(n)(2)式(1)与(2)相加可得f(m)+g(m)<f(n)+g(n)f(m)+g(m)<f(n)+g(n)f(m)+g(m)<f(n)+g(n),所以是单调递增的。在m<n时,有g(m)<g(n),且原创 2021-03-24 21:44:13 · 518 阅读 · 0 评论 -
<算法导论>练习3.1
3.1-1 由题目可知,f(n)>0且g(n)>0f(n)>0且g(n)>0f(n)>0且g(n)>0,并且他们均小于max(f(n),g(n))max(f(n),g(n))max(f(n),g(n)),而且max(f(n),g(n))max(f(n),g(n))max(f(n),g(n))一定小于f(n)+g(n)f(n)+g(n)f(n)+g(n),那么存在:0<=f(n)+g(n)2<=max(f(n)+g(n))<=f(n)+g(n)0&原创 2021-03-22 22:06:11 · 191 阅读 · 0 评论 -
<算法导论>第二章思考题
2-1a、对长度为k的子表使用插入排序最坏的情况下复杂度为Θ($k^{2}$),因此对n/k个每个长度为k的子表 排序最坏需要Θ(k^2 * n/k)=Θ(nk).b、$ J_\alpha(x) = \sum_{m=0}^\infty \frac{(-1)^m}{m! \Gamma (m + \alpha + 1)} {\left({ \frac{x}{2} }\right)}^{2m + \alpha} \text {,行内公式示例} $...原创 2021-03-20 21:05:12 · 254 阅读 · 1 评论 -
<算法导论>练习2.3
2.3-1[3] [41] [52] [26] [38] [57] [9] [49] [3|41] [26|52] [38|57] [9|49] [3|26|41|52] [9|38|49|57]原创 2021-03-18 21:47:05 · 107 阅读 · 1 评论 -
<算法导论>练习2.2
2.2-1只看最高次项,并忽略系数,时间复杂度为:Θ(n^3).2.2-2def swap(a,b): return b,adef select_sort(a): n=len(a) for i in range(n-1): minIndex=i for j in range(i+1,n): if a[j]<a[minIndex]: minIndex=j a[i],a[原创 2021-03-17 21:42:59 · 102 阅读 · 2 评论 -
<算法导论>练习2.1
2.1-12.1-2```python# 重写INSERTION-SORT# python 下列表从0 开始def INSERTION_SORT(A): for j in range(1,len(A)): key=A[j] i=j-1 while i>=0 and A[i]<key: A[i+1] = A[i] i-=1 A[i+1]=keya=[5,2,4,原创 2021-03-16 22:23:53 · 97 阅读 · 1 评论