算法导论上机报告Word格式文档下载.docx
- 文档编号:21682423
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:24
- 大小:26.58KB
算法导论上机报告Word格式文档下载.docx
《算法导论上机报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法导论上机报告Word格式文档下载.docx(24页珍藏版)》请在冰豆网上搜索。
11.J=1
12.Fork=ptor
13.IfL[i]<
=R[j]
14.A[k]=L[i]
15.I=i+1
16.ElseA[k]=R[j]
17.J=j+1
MERGE-SORT(A,p,r)
1、ifp<
r
2、q=(p+r)/2(取下限)
3、MERGE-SORT(A,p,q)
4、MERGE-SORT(A,q+1,r)
5、MERGE(A,p,q,r)
3、实验总结
在主函数中调用二分查找的时候,参数应该为BinSearch(a,j+1,n,x-a[j])从j+1开始遍历而不是都是从第一个开始。
在程序中由于程序语言规定数组的下标从0开始而算法伪代码要求从1开始,因此在定义数组大小的时候将数字加1,但是在编译运行的时候会得不到想要的结果,出现数组下标访问错误。
题目2
优先队列排序
实现优先队列排序算法,需要支持以下操作:
INSERT(S,x):
把元素x插入到集合S中
MAXMUM(S):
返回S中具有最大key的元素
EXTRACT-MAX(S):
去掉并返回S中的具有最大key的元素
INCREASE-KEY(S,x,k):
将元素x的关键字值增到k。
堆排序,运用堆来实现优先队列。
1、算法原理
1、堆排序算法是引用堆这个数据结构进行信息管理。
堆排序的时间复杂度是θ(nlgn),但是与归并排序不同的是堆排序具有空间的原址性,任何时候都只需要常数个额外的元素空间存储临时数据。
堆排序算法分为3个过程MAX-HEAPIEY:
调整堆以满足小顶堆性质其时间复杂度为θ(lgn);
BUILD-MAXHEAP:
从无序的输入数据数组中构造小顶堆,其时间复杂度为线性时间;
HEAP-SORT:
对数组进行原址排序,其时间复杂度为θ(nlgn)。
2、在堆的基础上实现优先队列INSERT、MAXMUM、EXTRACT-MAX、INCREASE-KEY时间复杂度为θ(lgn)。
2、伪代码
BUILD-MAX-HEAP(A)
1.=
2.Fori=2(取下限)downto1
3.MAX-HEAPIFY(A,i)
HEAPSORT(A)
1.Build-MAX-HEAP(A)
2.Fori=downto2
3.ExchangeA[1]withA[i]
4.=-1
5.MAX-HEAPIFY(A,1)
HEAP-MAIMUM(A)
1.returnA[1]
HEAP-EXTRACT-MAX(A)
1.if<
2.Error“heapunderflow”
3.Max=A[1]
4.A[1]=A[]
5.=-1
6.MAX-HEAPIFY(A,1)
7.Returnmax
HEAP-INCREASE-KEY(A,i,key)
1.ifkey<
A[i]
2.Error“newkeyissmallerthancurrentkey”
3.A[i]=key
4.Whilei>
1andA[PARENT(i)]<
5.ExchangeA[i]withA[PARENT(i)]
6.I=PARENT(i)
MAX-HEAP-INSERT(A,key)
1.=+1
2.A[]=负无穷
3.HEAP-INCREASE-KEY(A,,key)
三、实验总结
一开始没有理解将一个序列转换成小顶堆的过程,在编写MAX-EXSTRACT函数的时候,当去掉第一个元素后,程序并没有调用MAX-HEAP进行调整堆,因此最后序列是无序状态。
题目3
快速排序算法
实现快速排序算法。
使用Java实现插入排序算法。
一、算法原理
快速排序采用分治策略,时间复杂度为θ(nlgn),但是最坏情况下为θ(n2),并且快速排序算法属于原地排序,并不需要开辟空间。
快速排序复杂的步骤为其分解的步骤分解的过程数组A[p..r]被划分为两个子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每个元素都小于A[q],而A[q]也小于等于A[q+1..r]中的每个元素。
而在实现的过程总是选择将A[r]作为基准点进行划分A[p..r]数组。
二、伪代码
QUICKSORT(A,p,r)
1ifp<
r
2q=PARTITION(A,p,q)
3QUICKSORT(A,p,q-1)
4QUICKSORT(A,q+1,r)
PARTITION(A,p,r)
1x=A[r]
2i=p-1
3forj=ptor-1
4ifA[j]x
5i=i+1
6exchangeA[i]withA[j]
7exchangeA[i+1]withA[r]
8returni+1
问题答案:
当选取第一个或者最后一个为基准点时,当n个元素相同的时候为最坏情况比较次数为n*(n-1)/2;
快速排序比较次数最少为θ(nlgn),,最大的比较次数为θ(n2)。
题目4
用分治算法实现题目要求的时间复杂度运算
运用分治的策略将两个已经排好序的序列中,找出第k大的元素且要求时间复杂度为θ(lgm+lgn),其中m和n分别为两个序列的长度。
用分治算法实现题目要求。
如果K是中位数,则(M+n)是奇数还是偶数是有关系的。
如果是奇数,那么中位数唯一,如果是偶数就有两个中位数,可以随便取一个。
如果找到的第K大数是x,假如在A的位置是A(x),在B中的位置是B(x),则Ax+Bx-1=k是成立的。
接下来是具体实现逻辑:
1、首先假设K大数在A数组中,首先检查
(m/(m+n))*(k-1),假设其值为A1。
然后检查B中(k+1-(n/(m+n))*(k-1))假设为B1,检查A1、B1是否相等,或者大于B中的第(k+1-(n/(m+n))*(k-1)),并且小于(k+1-(n/(m+n))*(k-1))+1个元素。
满足条件就可以知道A1就是所求,否则看条件2。
2、如果两个条件都不满足,那么需要判断第K个元素是位于A1左边还是右边。
如果A1>
B1,那么K肯定不在A[0,(m/(m+n))*(k-1)]以及B[(k+1-(m/(m+n))*(k-1))+1,n]中;
如果A1<
B1,那么K肯定不在A[(m/(m+n))*(k-1),m]以及B[0,(k+1-(m/(m+n))*(k-1))]中。
第K个元素有可能在B中,同理可以假设在B中,再进行一次搜索。
复杂度log(m)+log(n)。
Searchkth(A,B,alow,ahigh,blow,bhigh,k)
1.amid=(alow+ahigh+1)/2
2.bmid=(blow+bhigh+1)/2
3.Ifalow>
ahigh
4.returnB[blow+k-1]
5.Ifblow>
bhigh
6.returnA[alow+k-1]
7.IfA[amid]<
=B[bmid]
8.IfA[amid]<
9.Ifk<
=amid-alow+bmid-blow+1
10.ReturnSearchkth(A,B,alow,ahigh,blow,bmid-1,k)
11.Else
12.ReturnSearchkth(A,B,amid+1,ahigh,blow,bhigh,k-(amid-alow)-1)
13.Else
14.Ifk<
15.ReturnSearchkth(A,B,alow,amid-1,blow,bhigh,k)
16.Else
17.ReturnSearchkth(A,B,alow,ahigh,bmid+1,bhigh,k-(bmid-blow)-1)
理解分治策略的三个步骤:
分解、解决和合并对于具体问题的具体表现,要善于根据时间复杂度与所学的算法进行结合,找出可以利用的地方。
2
矩阵链乘
用动态规划实现矩阵链乘,保证相乘的次数最少。
用动态规划实现矩阵链乘
1最优子结构为:
如果最优的加括号的方式将其分解为Ai..k与Ak+1..j的乘积则分别对Ai..k与Ak+1..j加括号的方式也一定是最优的。
2定义m[i,j]为计算矩阵Ai..j所需标量乘法次数的最小值,对于i=j时,矩阵链乘只包含唯一的矩阵Ai,因此不需要做任何标量乘法运算,所以m[i,i]=0;
当i<
j时利用最优子结构来计算m[i,j]。
3矩阵链乘的递归式
4在算法设计的时候需要m数组记录Ai..j最小相乘次数,s数组记录构造最优解所需要的信息,其记录的k值指出了AiAi+1Aj的最优括号化方案的分割点应在AkAk+1之间。
5矩阵链乘的时间复杂度为θ(n3)
MATRIX-CHAIN-ORDER(p)
=
m[1..n,1..n]ands[1..n-1,2..n]benewtables
i=1ton
4.M[i,i]=0
l=2ton
6.Fori=1ton-l+1
7.J=i+l-1
8.M[i,j]=无穷
9.Fork=itoj-1
10.Q=m[i,k]+m[k+1,j]+p(i-1)*p(k)*p(j)
11.Ifq<
m[i,j]
12.M[i,j]=q
13.S[i,j]=k
PRINT-OPTIMAL-PARENS(s,i,j)
1.ifi==j
2.Print“A”
3.Elseprint“(”
4.PRINT-OPTIMAL-PARENS(s,i,s[i,j])
5.PRINT-OPTIMAL-PARENS(s,s[i,j]+1,j)
6.Print“)”
矩阵链乘主要运用动态规划的思想,这种思想的重要之处在于找到最优的子结构,并设计出最优解的形式。
编程是并未遇到什么问题,过程较为顺利。
最长公共子序列
用动态规划求下列字符串的最长公共子序列。
用动态规划实现寻找最长公共子序列算法。
1最优子结构:
令X=<
x1,x2,..xm>
和Y=<
y1,y2,...,yn>
为两个序列Z=<
z1,z2,...,zk>
为X和Y的任意LCS。
如果xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的一个LCS;
如果xm≠yn,则zk≠xm意味着Z是Xm-1和Y的一个LCS;
如果xm≠yn,则zk≠yn意味着Z是X和Yn-1的一个LCS。
2定义一个b[i,j]指向表项对应计算c[i,j]时所选择的子问题最优解,过程返回表b和表c,c[m,n]保持X和Y的LCS长度。
3LCS的递归式为
4LCS的时间复杂度为θ(m+n),b表的空间复杂度为θ(mn)。
LCS-LENGTH(X,Y)
1.m=
2.n=
3.Letb[1..m,1..n]andc[0..m,0..n]benewtables
4.Fori=1tom
5.c[i,0]=0
6.Forj=0ton
7.c[0,j]=0
8.Fori=1tom
9.Forj=1ton
10.Ifxi==yj
11.c[i,j]=c[i-1,j-1]+1
12.b[i,j]=1
13.Elseifc[i-1,j]>
=c[i,j-1]
14.c[i,j]=c[i-1,j]
15.b[i,j]=2
16.Elsec[i,j]=c[i,j-1]
17.b[i,j]=3
;
PRINT-LCS(b,X,i,j)
1.ifi==0orj==0
2.Return;
3.Ifb[i,j]==1
4.PRINT-LCS(b,X,i-1,j-1)
5.Printxi
6.Elseifb[i,j]==2
7.PRINT-LCS(b,X,i-1,j)
PRINT-LCS(b,X,i,j-1)
用动态规划求取最长公共子序列的时候,要理解b数组的用途和使用。
一开始编程时将输入的字符串转化为字符出现问题,后来使用charAt()函数解决了问题。
最长公共子串
用动态规划求取以下字符串的最长公共子串。
用动态规划实现最长公共子串算法
1最优子结构令X=<
为X和Y的任意最长公共子串。
如果xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的一个最长公共子串;
如果xm≠yn,则zk≠xm意味着Z是Xm-1和Y的一个最长公共子串;
如果xm≠yn,则zk≠yn意味着Z是X和Yn-1的一个最长公共子串。
2定义L[i,j]为以x[i]和y[j]为结尾的相同子串的最大长度,记录着X和Y的最长公共子串的最大长度。
3最长公共子串的递归式
4最长公共子串的时间复杂度为θ(mn),空间复杂度为θ(mn)。
getLCString(str1,tr2)
len1=;
len2=;
maxLen=len1>
len2len1:
len2;
int[]max=newint[maxLen];
int[]maxIndex=newint[maxLen];
int[]c=newint[maxLen];
Letmax[0..maxlen-1],maxindex[0..maxlen-1]andc[0..maxlen-1]benewtables
Fori=0tolen2
forj=len1-1to0
ifstr2[i]==str1[j]
ifi==0orj==0
c[j]=1;
else
c[j]=c[j-1]+1;
else
c[j]=0;
ifc[j]>
max[0])
max[0]=c[j];
maxIndex[0]=j;
fork=1tomaxLen
max[k]=0;
maxIndex[k]=0;
elseifc[j]==max[0]
fork=1tomaxLen
ifmax[k]==0
max[k]=c[j];
maxIndex[k]=j;
forjtomaxLen
ifmax[j]>
0
Printj+1
fori=maxIndex[j]-max[j]+1tomaxIndex[j]
Printstr1[i]
要同上述的最长公共子序列进行对比区分他们的不同之处。
也要理解用动态规划求解时的相同之处和不同之处。
最大子段和
给定n个整数(可能为负数)组成的序列a[1],a[2]...a[n],求该序列a[i]+a[i+1]...a[j]的子段和的最大值。
用动态规划实现数列的最大和
定义当所给整数全为负数的时候,最大子段和为0,则最大子段和为max{0,a[i]+a[i+1]...+a[j]},1≤i≤j≤n
2引入一个辅助数组b,动态规划的分解分为两步:
(1)计算辅助数组的值;
(2)计算辅助数组的最大值。
辅助数组b[j]用来记录以j为尾的子段以及集合中的最大子段和。
3最大子段和的递归式
4最大子段和使用动态规划进行计算的时间复杂度为θ(n)。
Maxsum(A)
1.sum=0
2.temp=0
3.B[1..]=arraycopy(A)
4.Fori=0to
5.IfB[i]>
6.Sum=B[i]
7.Break
j=i+1to
9.IfB[j]>
10.Fora=itoj
11.temp=temp+b[a]
12.Iftemp>
sum
13.sum=temp
max
对比比较了动态规划和分治法的不同,感受到用动态规划解决的便捷。
题目5
最短路径问题
解决多级图中的最短路径问题
用动态规划解决多级图中的最短路径问题
1可以由图可知,图中的顶点讲图划分7个阶段,分别了解每个阶段可以有几种可供选择的点,引入f[k]表示状态k到终点状态的最短距离。
最优子结构为当前状态的f[k]由上个状态的f[k-1]和状态k-1到状态k的距离决定决策:
当前状态应在前一个状态的基础上获得。
决策需要满足规划方程,规划方程f(k)表示状态k到终点状态的最短距离。
2多段图最短路径的递归式
Shortestpath
letindexs[0..W1[0].length],isLabel[0..W1[0].length]
beanewtable
i_count=-1
distance=W1[start]
index=start
presentShortest=0
indexs[++i_count]=index;
isLabel[index]=true;
whilei_count<
W1[0].length
min=;
fori=0to
if!
isLabel[i]anddistance[i]!
=-1andi!
=index
ifdistance[i]<
min
min=distance[i]
index=i
ifindex==end
break;
isLabel[index]=true
indexs[++i_count]=index
ifW1[indexs[i_count-1]][index]==-1orpresentShortest+W1[indexs[i_count-1]][index]>
distance[index]
presentShortest=distance[index];
else
presentShortest+=W1[indexs[i_count-1]][index];
ifdistance[i]==-1andW1[index][i]!
=-1
distance[i]=presentShortest+W1[index][i];
elseifW1[index][i]!
=-1andpresentShortest+W1[index][i]<
distance[i])
distance[i]=presentShortest+W1[index][i];
returndistance[end]-distance[start];
遇到的问题:
无法将多段图的每个阶段点的状态表示并记录下来。
并不了解如何将动态规划与贪心算法的如迪杰斯特拉算法进行对比,真正从最优子结构将最短路径表示出来。
3
分数背包问题和0/1背包问题
解决分数背包和0/1背包问题
分别用贪心算法和动态规划实现分数背包问题和0/1背包问题
10-1背包问题:
选择n个元素中的若干个来形成最优解,假定为k个。
对于这k个元素a1,a2,...ak来说,它们组成的物品组合必然满足总重量<
=背包重量限制,而且它们的价值必然是最大的。
假定ak是我们按照前面顺序放入的最后一个物品,它的重量为wk,它的价值为vk。
前面k个元素构成了最优选择,把ak物品拿走,对应于k-1个物品来说,它们所涵盖的重量范围为0-(W-wk)。
假定W为背包允许承重的量,最终的价值是V,剩下的物品所构成的价值为V-vk。
这剩下的k-1个元素构成了W-wk的最优解。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 导论 上机 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)