算法设计及的分析部分算法伪代码
第三章蛮力法
1.选择排序
?SelectionSort(A[0..n-1])
for i=0 to n-2 do
min=i
for j=i+1 to n-1 do
if A[j] min=j swap A[i] and A[min] 2.冒泡排序 ?BubbleSort(A[0..n-1]) // 输入:数组A,数组中的元素属于某偏序集 // 输出:按升序排列的数组A for i=0 to n-2 do for j=0 to n-2-i do if A[j+1] 3.改进的冒泡算法 ?ALGORITHM BubbleSortImproved( A[0,…,n – 1] ) // 冒泡排序算法的改进 // 输入:数组A,数组中的元素属于某偏序集 // 输出:按升序排列的数组A for i ←0 to n – 2 do flag ←True for j ←0 to n – 2 – i do if A[j+1] < A[j] swap(A[j], A[j+1]) flag ←False // 如果在某一轮的比较中没有交换,则flag为True,算法结束 if flag = True return 4.顺序查找算法 算法SwquentialSearch2(A[0...n],k) //顺序查找算法的实现,它用了查找键来作限位器 //输入:一个n个元素的数组A和一个查找键K //输出:第一个值等于K的元素的位置,如果找不到这样的元素就返回-1 A[n]<--k i<--0 while A[i]!=K do i<--i+1 if i Else return -1 5.蛮力字符串匹配 算法BruteForceStringMatch(T[0...n-1],P[0...m-1]) //该算法实现了蛮力字符串匹配 //输入:一个n个字符的数组T[0...n-1]代表一段文本 // 一个m个字符的数组P[0..m-1]代表一个模式 //输出:如果查找成功的话,返回文本的第一个匹配字串中第一个字符的位置,// 否则返回-1 For i<--0 to n-m do j<--0 While j j<--i+1 If j=m return i return -1 ?合并排序最差Θ(nlog2n) ?快速排序最优Θ(nlog2n) 最差Θ(n2) 平均Θ(1.38nlog2n) ?选择排序Θ(n2) ?冒泡排序Θ(n2) ?插入排序最差Θ(n2) ?最优Θ(n) ?平均Θ(n2) 第四章分治法 合并排序 算法MergeSort(A[0..n-1] ) // 递归调用mergesort来对数组A[0...n-1] 排序 // 输入:一个可排序数组A[0..n-1] // 输出:非降序排列的数组A[0..n-1] if n > 1 copy A[0..?n/2?-1] to B[0..?n/2?-1] copy A[?n/2?..n-1] to C[0..?n/2?-1] MergeSort( B ) MergeSort( C ) Merge( B,C,A ) 两个数组合并的算法 算法Merge(B[0..p-1],C[0..q-1],A[0..p+q-1]) //将两个有序数组合并成一个有序的数组 //输入:两个有序数组B[0...p-1]和C[0...q-1] //输出:A[0..p+q-1]中已经有序存放了B和C中的元素 i=0,j=0,k=0; while i if B[i]≤C[j] A[k]=B[i], i=i+1 else A[k]=C[j], j=j+1 k=k+1 if i=p copy C[j..q-1] to A[k..p+q-1] else copy B[i..p-1] to A[0..p+q-1] 快速排序算法 QuickSort(A[l..r]) // 使用快速排序法对序列或者子序列排序 // 输入:子序列A[l..r]或者序列本身A[0..n-1] // 输出:非递减序列A if l < r s ←Partition( A[l..r] ) QuickSort( A[l..s-1] ) QuickSort( A[s+1..r] ) //s是中轴元素/基准点,是数组分区位置的标志 实现分区的算法 Partition( A[l..r] ) // 输入:子数组A[l..r] // 输出:分裂点/基准点pivot的位置 p ←A[l]i ←l; j ←r+1 repeat repeat i ←i + 1until A[i] ≥p repeat j ←j –1 until A[j] ≤p swap( A[i], A[j] ) until i ≥j swap( A[i], A[j] ) swap( A[l], A[j] ) return j 折半查找 BinarySearch( A[0..n-1], k ) // 输入:已排序大小为n的序列A,待搜索对象k // 输出:如果搜索成功,则返回k的位置,否则返回-1 l=0,r=n-1; While l≤r mid= ?(l+r)/2? if k = A[mid] return mid else if k < A[mid] r=m-1 else l=m+1 return -1 Strassen矩阵 ?Strassen方法 M1=A11(B12-B22) M2=(A11+A12)B22 M3=(A21+A22)B11 M4=A22(B21-B11) M5=(A11+A22)(B11+B22) M6=(A12-A22)(B21+B22) M7=(A11-A21)(B11+B12) 第五章减治法 插入排序 ?ALGORITHM InsertionSort( A[0..n-1] ) // 对给定序列进行直接插入排序 // 输入:大小为n的无序序列A // 输出:按非递减排列的序列A for i ←1 to n-1 do temp ←A[i] j ←i-1 while j ≥0 and A[j] > temp do A[j+1] ←A[j] j ←j –1 A[j+1] ←temp 深度优先查找 算法BFS(G) //实现给定图的深度优先查找遍历 //输入:图G= //输出:图G的顶点,按照被DFS遍历第一次访问到的先后次序,用连续的整数标记,将V中的每个顶点标记为0,表示还“未访问” count =0//记录这是第几个访问的节点 mark each vertex with 0//标记为unvisited for each vertex v∈V do if v is marked with 0 dfs(v) dfs(v) //递归访问所有和v相连接的未访问顶点,然后按照全局变量count的值 //根据遇到它们的先后顺序,给它们附上相应的数字 count = count + 1 mark v with count for each vertex w adjacent to v do if w is marked with 0 dfs(w) 广度优先 BFS(G) /实现给定图的深度优先查找遍历 //输入:图G= //输出:图G的顶点,按照被BFS遍历第一次访问到的先后次序,用连续的整数标记,将V中的每个顶点标记为0,表示还“未访问” count =0 mark each vertex with 0 for each vertex v∈V do bfs(v) bfs(v) //递归访问所有和v相连接的未访问顶点,然后按照全局变量count的值 //根据遇到它们的先后顺序,给它们附上相应的数字 count = count + 1 mark v with count initialize queue with v while queue is not empty do a = front of queue for each vertex w adjacent to a do if w is marked with 0 count = count + 1 mark w with count add w to the end of the queue remove a from the front of the queue 拓扑排序 第六章变治法 Gauss消去法 ?GaussElimination(A[1..n], b[1..n]) // 输入:系数矩阵A及常数项b // 输出:方程组的增广矩阵等价的上三角矩阵 for i=1 to n do A[i][n+1] =b[i] for j= i+1 to n do for k = i to n+1 do A[j][k] = A[j][k] – A[i][k]*A[j][i]/A[i][i] 堆排序 ?堆排序主要包括两个步骤: ?对于给定的数组构造相应的堆。 ?对所构造的堆执行n-1次删除堆的根结点的操作,把删除得到的结点保存在给定数组中。 ? 1 构造堆的效率是多少? ?O(n) ? 2 推排序的效率 ?O(nlogn) Horner法则 第七章时空权衡 计数排序 比较计数算法 算法ComparisonCountingSort(A[0...n-1]) //用比较计数法对数组排序 //输入:可排序数组A[0...n-1] //输出:将A中的元素按照升序排列的数组S[0..n-1] For i=0 to n-1 do count[i]=0 For i=0 to n-2 do For j=i+1 to n-1 do ifA[i] Count[j]=Count[j]+1 Else Count[i]=Count[i]+1 For i=0 to n-1 do S[Count[i]]=A[i] Return S C(n)=n(n-1)/2 第八章动态规划 WARSHALL算法 ?void WARSHALL(m) for (i=1; i<=n; i++ ) for (j=1; j<=n; j++ ) if(m [j,i]=T) for (k=1; i<=n; i++ ) m [j,k] + =m [i,k]; (4) ?该算法由邻接矩阵在原矩阵构建传递闭包 ?WARSHALL算法的时间复杂度为O(n3)。Floyd算法 ?算法Floyd(W[1..n,1..n]) // 实现计算完全最短路径的Floyd算法 // 输入:图的权重矩阵W // 输出:包含最短路径长度的距离矩阵 算法递归典型例题 实验一:递归策略运用练习 三、实验项目 1.运用递归策略设计算法实现下述题目的求解过程。 题目列表如下: (1)运动会开了N天,一共发出金牌M枚。第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。到了第N天刚好还有金牌N枚,到此金牌全部发完。编程求N和M。 (2)国王分财产。某国王临终前给儿子们分财产。他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i 个儿子i份,再加上剩余财产的1/10。每个儿子都窃窃自喜。以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。请用程序回答,老国王共有几个儿子?财产共分成了多少份? 源程序: (3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。问这鱼缸里原有多少条金鱼? (4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少? (5)猴子吃桃。有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子? (6)小华读书。第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页? (7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子? 四、实验过程 (一)题目一:…… 1.题目分析 由已知可得,运动会最后一天剩余的金牌数gold等于运动会举行的天数由此可倒推每一 天的金牌剩余数,且每天的金牌数应为6的倍数。 2.算法构造 设运动会举行了N天, If(i==N)Gold[i]=N; Else gold[i]=gold[i+1]*7/6+i; 伪代码 伪码(Pseudocode)是一种算法描述语言。使用伪码的目的是使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java等)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。介于自然语言与编程语言之间。以编程语言的书写形式指明算法职能。使用伪代码,不用拘泥于具体实现。相比程序语言(例如Java, C++,C, Dephi 等等)它更类似自然语言。它是半角式化、不标准的语言。可以将整个算法运行过程的结构用接近自然语言的形式(可以使用任何一种你熟悉的文字,关键是把程序的意思表达出来)描述出来。 1.简介 定义 人们在用不同的编程语言实现同一个算法时意识到,他们的实现(注意:这里是实现,不是功能)很不同。尤其是对于那些熟练于不同编程语言的程序员要理解一个(用其他编程语言编写的程序的)功能时可能很难,因为程序语言的形式限制了程序员对程序关键部分的理解。这样伪代码就应运而生了。伪代码提供了更多的设计信息,每一个模块的描述都必须与设计结构图一起出现。伪代码是一种非正式的,类似于英语结构的,用于描述模块结构图的语言。 应用领域 当考虑算法功能(而不是其语言实现)时,伪码常常得到应用。伪码中常被用于技术文档和科学出版物中来表示算法,也被用于在软件开发的实际编码过程之前表达程序的逻辑。伪代码不是用户和分析师的工具,而是设计师和程序员的工具。计算机科学在教学中通常使用虚拟码,以使得所有的程序员都能理解。综上,简单地说,让人便于理解的代码。不依赖于语言的,用来表示程序执行过程,而不一定能编译运行的代码。在数据结构讲算法的时候用的很多。伪代码用来表达程序员开始编码前的想法。 2.语法规则 例如,类Pascal语言的伪码的语法规则是:在伪码中,每一条指令占一行(else if,例外)。指令后不跟任何符号(Pascal和C中语句要以分号结尾)。书写上的“缩进”表示程序中的分支程序结构。这种缩进风格也适用于if-then-else语句。用缩进取代传统Pascal中的begin和end语句来表示程序 1.一个算法就是一个有穷规则的集合,其中之规则规定了解决某一特殊类型问题的一系列运算,此外,算法还应具有以下五个重要特性:_________,________,________,__________,__________。 2.算法的复杂性有_____________和___________之分,衡量一个算法 好坏的标准是______________________。 3.某一问题可用动态规划算法求解的显着特征是 ____________________________________。 4.若序列X={B,C,A,D,B,C,D},Y={A,C,B,A,B,D,C,D},请给出序列X 和Y的一个最长公共子序列_____________________________。 5.用回溯法解问题时,应明确定义问题的解空间,问题的解空间至少应包含___________。 6.动态规划算法的基本思想是将待求解问题分解成若干____________,先求解___________,然后从这些____________的解得到原问题的解。 7.以深度优先方式系统搜索问题解的算法称为_____________。 背包问题的回溯算法所需的计算时间为_____________,用动态规划算法所需的计算时间为____________。 9.动态规划算法的两个基本要素是___________和___________。? 10.二分搜索算法是利用_______________实现的算法。 二、综合题(50分) 1.写出设计动态规划算法的主要步骤。 2.流水作业调度问题的johnson算法的思想。 算法设计与分析实验报告 姓名:888 学号:129074999 老师:许精明 实验1:杨辉三角 解法思路: 根据杨辉三角中除最外层(不包括杨辉三角底边)的数为1外,其余的数都是它肩上两个数之和这一性质,用数组输出杨辉三角。 根据杨辉三角的第n行恰好是C(n,0)~C(n,n),可以不用数组输出,而用动态规划。这里的C表示组合。 注:由于为了便于控制输出格式,程序中的最大输出行确定的较小,但程序本身并没有错误。若要输出更多行,需要增加控制输出格式的语句。 解法一:数组 #include 4.29 算法练习讲义 1、根据如图所示的伪代码,当输入b a ,分别为2,3时,最后输出的m 的值是________ 第4题图 2.右图是一个算法流程图,则输出的k 的值是 . 3.右图是一个算法的流程图,则输出的的值是. n 4.右图是一个算法流程图,则输出的n 的值是. 5.根据如图所示的伪代码,可知输出的结果S 为_____. 6 若输入变量N 的值为3,则输出的值为;若输出变量的S 的值为30,则变量N 的值为。 7.如果,当126,9,8.5x x P ===时3x =。 8、下图是一个算法的流程图,则输出的S的值是。 ,则判断框内可填写。 9.阅读流程图,若输出的S的值为7 10.运行如图所示的流程图,若输出的结果是62,则判断框中整数M的值是。 11.下图是某算法的流程图,则程序运行后所输出的S的值是。 12.上图是一个算法流程图,则输出的x的值是。 13.执行如图所示的流程图,输出的k的值为。 14、根据如图所示的伪代码,可知输出的结果S为________. 15、根据下图所示的伪代码,可知输出的结果S为 16.执行如图所示的程序框图,输出的x值为________. (第16题图) 17.如图,运行伪代码所示的程序,则输出的结果是____. 18.右边程序输出的结果是____. 19.如右图是一个算法流程图,则输出S的值是. 20.根据如图所示的伪代码,最后中输出的a的值为. 21.某程序框图如右上图所示,则该程序运行后输出的S值是. 22.如图是一个算法流程图,则输出的s的值是____. 目录 算法概论 (1) 序言 (1) 第一章 (2) 乘法 (2) 除法 (2) 两数的最大公因数 (2) 扩展 (2) RSA (3) 第二章:分治算法 (3) 整数相乘的分治算法 (3) 递推式 (3) 2.3合并排序 (3) 第三章图的分解 (4) 3.2.1寻找从给定顶点出发的所有可达顶点 (4) 3.2.2 深度优先搜索 (4) 第四章 (4) 4.2、广度优先搜索 (4) 4.4.1、dijkstra最短路径算法 (5) 4.6.1、含有负边 (5) Bellman-Ford算法 (6) 4.7、有向无环图的最短路径 (6) 第五章贪心算法 (6) 5.1 最小生成树 (6) 算法概论 序言 Fibonacci数列: 死板的算法: function Fib1(n) If n=0:return 0 If n=1:return 1 Return fib1(n-1)+fib1(n-2) (递归,很多计算是重复的,不必要) 合理的算法: functionFib2(n) If n=0:return 0 Create an array f[0…n] f[0]=0,f[1]=1 fori=2…n: f[i]=f[i-1] + f[i-2] return f[n] (随时存储中间计算结果,之后直接调用) 大O符号:若存在常数c>0,使得f(n)<=c*g(n)成立,则f=O(g)。f增长的速度慢于g。第一章 乘法: functionMultiply(x,y) If y=0:return 0 z=multiply(x,y/2)//向下取整 If y is even: //even---偶数 return 2z else: return x+2z 除法: functionDivide(x,y) If x=0: return (q,r)=(0,0) (q,r)=divide( x/2 ,y) //向下取整 q=2*q,r=2*r if x is odd:r=r+1 if r>=y :r=r-y,q=q+1 return (q,r) p22 两数的最大公因数: function Euclid(a,b) if b=0: return a return Euclid(b,a mod b) 扩展: 算法分析与设计 学习总结 题目:算法分析与设计学习总结 学院信息科学与工程学院专业2013级计算机应用技术 届次 学生姓名 学号2013110657 二○一三年一月十五日 算法分析与设计学习总结 本学期通过学习算法分析与设计课程,了解到:算法是一系列解决问题的清晰指令,代表着用系统的方法描述解决问题的策略机制。算法能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂性和时间复杂度来衡量。算法可以使用自然语言、伪代码、流程图等多种不同的方法来描述。计算机系统中的操作系统、语言编译系统、数据库管理系统以及各种各样的计算机应用系统中的软件,都必须使用具体的算法来实现。算法设计与分析是计算机科学与技术的一个核心问题。 设计的算法要具有以下的特征才能有效的完成设计要求,算法的特征有:(1)有穷性。算法在执行有限步后必须终止。(2)确定性。算法的每一个步骤必须有确切的定义。(3)输入。一个算法有0个或多个输入,作为算法开始执行前的初始值,或初始状态。(4)输出。一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的。 (5)可行性。在有限时间内完成计算过程。 算法设计的整个过程,可以包含对问题需求的说明、数学模型的拟制、算法的详细设计、算法的正确性验证、算法的实现、算法分析、程序测试和文档资料的编制。算法可大致分为基本算法、数据结构的算法、数论与代数算法、计算几何的算法、图论的算法、动态规划以及数值分析、加密算法、排序算法、检索算法和并行算法。 经典的算法主要有: 1、穷举搜索法 穷举搜索法是对可能是解的众多候选解按某种顺序进行逐一枚举和检验,bing从中找出那些符合要求的候选解作为问题的解。 穷举算法特点是算法简单,但运行时所花费的时间量大。有些问题所列举书来的情况数目会大得惊人,就是用高速计算机运行,其等待运行结果的时间也将使人无法忍受。我们在用穷举算法解决问题是,应尽可能将明显不符合条件的情况排除在外,以尽快取得问题的解。 2、迭代算法 迭代法是数值分析中通过从一个初始估计出发寻找一系列近似解来解决问题(一般是解方程或方程组)的过程,为实现这一过程所使用的方法统称为迭代法。迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行: (1)选一个方程的近似根,赋给变量x0。 (2)将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0。 (3)当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。 若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。 3、递推算法 递推算法是利用问题本身所具有的一种递推关系求问题解的一种方法。它把问题分成若干步,找出相邻几步的关系,从而达到目的。 4、递归算法 递归算法是一种直接或间接的调用自身的算法。 能采用递归描述的算法通常有这样的特征:为求解规模为n的问题,设法将它分解成规模较小的问题,然后从这些小问题的解方便地构造出大问题的解,并且这些规模较小的问题也能采用同样的分解和综合方法,分解成规模更小的问题,并从这些更小问题的解构造出规模 习题1.1 5..证明等式gcd(m,n)=gcd(n,m mod n)对每一对正整数m,n都成立. Hint: 根据除法的定义不难证明: 如果d整除u和v, 那么d一定能整除u±v; 如果d整除u,那么d也能够整除u的任何整数倍ku. 对于任意一对正整数m,n,若d能整除m和n,那么d一定能整除n和r=m mod n=m-qn;显然,若d 能整除n和r,也一定能整除m=r+qn和n。 数对(m,n)和(n,r)具有相同的公约数的有限非空集,其中也包括了最大公约数。故gcd(m,n)=gcd(n,r) 6.对于第一个数小于第二个数的一对数字,欧几里得算法将会如何处理?该算法在处理这种输入的过程中,上述情况最多会发生几次? Hint: 对于任何形如0<=m 【题目1】N皇后问题(八皇后问题的扩展) 【题目2】排球队员站位问题 【题目3】把自然数N分解为若干个自然数之和 【题目4】把自然数N分解为若干个自然数之积 【题目5】马的遍历问题 【题目6】加法分式分解 【题目7】地图着色问题 【题目8】在n*n的正方形中放置长为2,宽为1的长条块 【题目9】找迷宫的最短路径。(广度优先搜索算法) 【题目10】火车调度问题 【题目11】农夫过河 【题目12】七段数码管问题。 【题目13】把1-8这8个数放入下图8个格中,要求相邻的格(横,竖,对角线)上填的数不连续 【题目14】在4×4的棋盘上放置8个棋,要求每一行,每一列上只能放置2个 【题目15】迷宫问题.求迷宫的路径.(深度优先搜索法) 【题目16】一笔画问题 【题目17】城市遍历问题 【题目18】棋子移动问题 【题目19】求集合元素问题(1,2x+1,3X+1类) 【题目1】N皇后问题(含八皇后问题的扩展,规则同八皇后):在N*N的棋盘上,放置N个皇后,要求每一横行,每一列,每一对角线上均只能放置一个皇后,问可能的方案及方案数。 const max=8; var i,j:integer; a:array[1..max] of 0..max; {放皇后数组} b:array[2..2*max] of boolean;{/对角线标志数组} c:array[-(max-1)..max-1] of boolean; {\对角线标志数组} col:array[1..max] of boolean; {列标志数组} total:integer; {统计总数} procedure output; {输出} var i:integer; begin write('No.':4,'[',total+1:2,']'); for i:=1 to max do write(a[i]:3);write(' '); if (total+1) mod 2 =0 then writeln; inc(total); end; function ok(i,dep:integer):boolean; {判断第dep行第i列可放否} begin ok:=false; if ( b[i+dep]=true) and ( c[dep-i]=true) {and (a[dep]=0)} and (col[i]=true) then ok:=true 伪代码的使用 伪代码(Pseudocode)是一种算法描述语言。使用为代码的目的是为了使被描述的算法可以容易地以任何一种编程语言(Pascal, C, Java, etc)实现。因此,伪代码必须结构清晰,代码简单,可读性好,并且类似自然语言。 下面介绍一种类Pascal语言的伪代码的语法规则。 伪代码的语法规则 1.在伪代码中,每一条指令占一行(else if例外,),指令后不跟任何符号 (Pascal和C中语句要以分号结尾); 2.书写上的“缩进”表示程序中的分支程序结构。这种缩进风格也适用于 if-then-else语句。用缩进取代传统Pascal中的begin和end语句来表示程序的块结构可以大大提高代码的清晰性;同一模块的语句有相同的缩进量,次一级模块的语句相对与其父级模块的语句缩进; 例如: line 1 line 2 sub line 1 sub line 2 sub sub line 1 sub sub line 2 sub line 3 line 3 而在Pascal中这种关系用begin和end的嵌套来表示, line 1 line 2 begin sub line 1 sub line 2 begin sub sub line 1 sub sub line 2 end; sub line 3 end; line 3 在C中这种关系用{ 和 } 的嵌套来表示, line 1 line 2 { sub line 1 sub line 2 { sub sub line 1 sub sub line 2 } sub line 3 } line 3 3.在伪代码中,通常用连续的数字或字母来标示同一即模块中的连续语句, 有时也可省略标号。 例如: 1. line 1 2. line 2 a. sub line 1 b. sub line 2 1. sub sub line 1 2. sub sub line 2 c. sub line 3 3. line 3 4.符号△后的内容表示注释; 5.在伪代码中,变量名和保留字不区分大小写,这一点和Pascal相同,与 C或C++不同; 6.在伪代码中,变量不需声明,但变量局部于特定过程,不能不加显示的说 明就使用全局变量; 7.赋值语句用符号←表示,x←exp表示将exp的值赋给x,其中x是一个变 量,exp是一个与x同类型的变量或表达式(该表达式的结果与x同类型); 多重赋值i←j←e是将表达式e的值赋给变量i和j,这种表示与j←e 和i←e等价。 例如: x←y x←20*(y+1) x←y←30 成绩评定表 课程设计任务书 摘要 算法分析是对一个算法需要多少计算时间和存储空间作定量的分析。算法(Algorithm)是解题的步骤,可以把算法定义成解一确定类问题的任意一种特殊的方法。在计算机科学中,算法要用计算机算法语言描述,算法代表用计算机解一类问题的精确、有效的方法。 分治法字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。在一个2^k*2^k的棋盘上,恰有一个放歌与其他方格不同,且称该棋盘为特殊棋盘。 回溯法的基本做法是深度优先搜索,是一种组织得井井有条的、能避免不必要重复搜索的穷举式搜索算法。数字拆分问题是指将一个整数划分为多个整数之和的问题。利用回溯法可以很好地解决数字拆分问题。将数字拆分然后回溯,从未解决问题。 关键词:分治法,回溯法,棋盘覆盖,数字拆分 目录 1分治法解决期盼覆问题错误!未定义书签。 问题描述错误!未定义书签。 问题分析错误!未定义书签。 算法设计错误!未定义书签。 算法实现错误!未定义书签。 结果分析错误!未定义书签。 算法分析错误!未定义书签。 2回溯法解决数字拆分问题错误!未定义书签。 问题描述错误!未定义书签。 问题分析错误!未定义书签。 算法设计错误!未定义书签。 算法实现错误!未定义书签。 结果分析错误!未定义书签。 参考文献错误!未定义书签。 1分治法解决期盼覆问题 问题描述 在一个2k×2k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中出现的位置有4k中情形,因而有4k中不同的棋盘,图(a)所示是k=2时16种棋盘中的一个。棋盘覆盖问题要求用图(b)所示的4中不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且热河亮哥L型骨牌不得重复覆盖 问题分析 用分治策略,可以设计解决棋盘问题的一个简介算法。 当k>0时,可以将2^k *2^k棋盘分割为4个2^k-1 * 2^k-1子棋盘。由棋盘覆盖问题得知,特殊方格必位于4个较小的子棋盘中,其余3个子棋盘中无特殊方格。为了将3个无特殊方格的子棋盘转化为特殊棋盘可以将一个L型骨牌覆盖这3个较小棋盘的会合处,所以,这3个子棋盘上被L型覆盖的方格就成为给棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归的使用这种分割,直至棋盘简化为1*1棋盘为止。 。 算法设计 将2^k x 2^k的棋盘,先分成相等的四块子棋盘,其中特殊方格位于四个中的一个,构造剩下没特殊方格三个子棋盘,将他们中的也假一个方格设为特殊方格。如果是: 左上的子棋盘(若不存在特殊方格)----则将该子棋盘右下角的那个方格假设为特殊方格 右上的子棋盘(若不存在特殊方格)----则将该子棋盘左下角的那个方格假设为特殊方格 左下的子棋盘(若不存在特殊方格)----则将该子棋盘右上角的那个方格假设为特殊方格 右下的子棋盘(若不存在特殊方格)----则将该子棋盘左上角的那个方格假设为特殊方格 当然上面四种,只可能且必定只有三个成立,那三个假设的特殊方格刚好构成一个L型骨架,我们可以给它们作上相同的标记。这样四个子棋盘就分别都和原来的大棋盘类似,我们就可以用递归算法解决。 。 算法实现 #include<> int tile=1; int board[100][100]; void chessBoard(int tr, int tc, int dr, int dc, int size) { if(size==1) return; int t=tile++; int s=size/2; if(dr 中国地质大学研究生课程论文封面 课程名称算法设计与分析 教师姓名 XXXXXX 研究生姓名侉哥 研究生学号 1201666666 研究生专业 XXXXXXXXXXXXX 所在院系计算机学院 类别: A.博士 B.硕士√ C.进修生 日期: 2016.1.12 《算法设计与分析》课程报告 本学期,我选修了XXX教授的《算法分析与算法设计》这门课程。课堂上,戴老师条理清晰、深入浅出地为我们讲解了算法复杂度、分支算法、贪心算法、动态规划算法、基本检索与周游方法、回溯算法和分支-限界法等知识内容。此外,还为我们介绍了NP-难度和NP-完全的问题。 第一章导引与基本数据结构 老师首先引入编程实现两矩阵相乘和编程实现求证平行四边形两个例子,举例说明现阶段计算机算法可以解决的问题(计算问题)和不可以解决(几何证明)的问题。 接着老师指出算法是指计算的方法,而计算是基于规则的变换,物理角度可以理解为是基于规则的物理状态的变换,也可以理解为是基于规则的信息的变换。接着老师讲解了算法的三个重要特性:无二义性、能解性、有限性。当然算法的特性还包括输入和输出。 之后老师讲解了算法设计与分析的含义,讲了计算模型的假设和两个重要的量:问题的规模和频率计数。也就是空间复杂度和时间复杂度的分析方法,根据时间复杂度,算法一般可以分为多项式时间复杂度(P算法)和指数时间复杂度(NP算法)。 多项式时间内可以执行完成的算法是P算法,例如时间复杂度为: O(1) 遗传算法( GA , Genetic Algorithm ) ,也称进化算法。遗传算法是受达尔文的进化论的启发,借鉴生物进化过程而提出的一种启发式搜索算法。因此在介绍遗传算法前有必要简单的介绍生物进化知识。 一.进化论知识 作为遗传算法生物背景的介绍,下面内容了解即可: 种群(Population):生物的进化以群体的形式进行,这样的一个群体称为种群。 个体:组成种群的单个生物。 基因 ( Gene ) :一个遗传因子。 染色体 ( Chromosome ):包含一组的基因。 生存竞争,适者生存:对环境适应度高的、牛B的个体参与繁殖的机会比较多,后代就会越来越多。适应度低的个体参与繁殖的机会比较少,后代就会越来越少。 遗传与变异:新个体会遗传父母双方各一部分的基因,同时有一定的概率发生基因变异。 简单说来就是:繁殖过程,会发生基因交叉( Crossover ) ,基因突变( Mutation ) ,适应度( Fitness )低的个体会被逐步淘汰,而适应度高的个体会越来越多。那么经过N代的自然选择后,保存下来的个体都是适应度很高的,其中很可能包含史上产生的适应度最高的那个个体。 二.遗传算法思想 借鉴生物进化论,遗传算法将要解决的问题模拟成一个生物进化的过程,通过复制、交叉、突变等操作产生下一代的解,并逐步淘汰掉适应度函数值低的解,增加适应度函数值高的解。这样进化N代后就很有可能会进化出适应度函数值很高的个体。 举个例子,使用遗传算法解决“0-1背包问题”的思路:0-1背包的解可以编码为一串0-1字符串(0:不取,1:取);首先,随机产生M个0-1字符串,然后评价这些0-1字符串作为0-1背包问题的解的优劣;然后,随机选择一些字符串通过交叉、突变等操作产生下一代的M个字符串,而且较优的解被选中 伪代码 伪代码(Pseudocode)是一种算法描述语言。使用伪代码的目的是为了使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java,etc)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。介于自然语言与编程语言之间。以编程语言的书写形式指明算法职能。使用伪代码, 不用拘泥于具体实现。相比程序语言(例如Java, C++,C, Dephi 等等)它更类似自然语言。它是半角式化、不标准的语言。可以将整个算法运行过程的结构用接近自然语言的形式(可以使用任何一种你熟悉的文字,关键是把程序的意思表达出来)描述出来。 定义 人们在用不同的编程语言实现同一个算法时意识到,他们的实现(注意:这里是实现,不是功能)很不同。尤其是对于那些熟练于不同编程语言的程序员要理解一个(用其他编程语言编写的程序的)功能时可能很难,因为程序语言的形式限制了程序员对程序关键部分的理解。这样伪代码就应运而生了。伪代码提供了更多的设计信息,每一个模块的描述都必须与设计结构图一起出现。伪代码是一种非正式的,类似于英语结构的,用于描述模块结构图的语言。 应用领域 当考虑算法功能(而不是其语言实现)时,伪代码常常得到应用。伪码中常被用于技术文档和科学出版物中来表示算法,也被用于在软件开发的实际编码过程之前表达程序的逻辑。伪代码不是用户和分析师的工具,而是设计师和程序员的工具。计算机科学在教学中通常使用虚拟码,以使得所有的程序员都能理解。综上,简单的说,让人便于理解的代码。不依赖于语言的,用来表示程序执行过程,而不一定能编译运行的代码。在数据结构讲算法的时候用的很多。伪代码用来表达程序员开始编码前的想法。 语法规则 例如,类Pascal语言的伪代码的语法规则是:在伪代码中,每一条指令占一行(else if,例外)。指令后不跟任何符号(Pascal和C中语句要以分号结尾)。书写上的“缩进”表示程序中的分支程序结构。这种缩进风格也适用于if-then-else语句。用缩进取代传统Pascal中的begin和end语句来表示程序的块结构可以大大提高代码的清晰性;同一模块的语句有相同的缩进量,次一级模块的语句相对与其父级模块的语句缩进。 伪代码实例 伪代码:是用介于自然语言和计算机语言之间的文字和符号(包括数学符号)来描述算法。【简单示例】输入3个数,打印输出其中最大的数。可用如下的伪代 伪代码及其实例讲解 伪代码(Pseudocode)是一种算法描述语言。使用伪代码的目的是为了使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java,etc)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。介于自然语言与编程语言之间。 它以编程语言的书写形式指明算法的职能。相比于程序语言(例如Java, C++,C, Dephi 等等)它更类似自然语言。它是半角式化、不标准的语言。我们可以将整个算法运行过程的结构用接近自然语言的形式(这里,你可以使用任何一种你熟悉的文字,中文,英文等等,关键是你把你程序的意思表达出来)描述出来. 使用伪代码, 可以帮助我们更好的表述算法, 不用拘泥于具体的实现. 人们在用不同的编程语言实现同一个算法时意识到,他们的实现(注意:这里是实现,不是功能)很不同。尤其是对于那些熟练于不同编程语言的程序员要理解一个(用其他编程语言编写的程序的)功能时可能很难,因为程序语言的形式限制了程序员对程序关键部分的理解。这样伪代码就应运而生了。 当考虑算法功能(而不是其语言实现)时,伪代码常常得到应用。计算机科学在教学中通常使用虚拟码,以使得所有的程序员都能理解。 综上,简单的说,让人便于理解的代码。不依赖于语言的,用来表示程序执行过程,而不一定能编译运行的代码。在数据结构讲算法的时候用的很多。 语法规则 例如,类Pascal语言的伪代码的语法规则是:在伪代码中,每一条指令占一行(else if,例外)。指令后不跟任何符号(Pascal和C中语句要以分号结尾)。书写上的“缩进”表示程序中的分支程序结构。这种缩进风格也适用于if-then-else语句。用缩进取代传统Pascal中的begin和end语句来表示程序的块结构可以大大提高代码的清晰性;同一模块的语句有相同的缩进量,次一级模块的语句相对与其父级模块的语句缩进。 算法的伪代码语言在某些方面可能显得不太正规,但是给我们描述算法提供了很多方便,并且可以使我们忽略算法实现中很多麻烦的细节。通常每个算法开始时都要描述它的输入和输出,而且算法中的每一行都给编上号码,在解释算法的过程中会经常使用算法步骤中的行号来指代算法的步骤。算法的伪代码描述形式上并不是非常严格,其主要特性和通常的规定如下: 1) 算法中出现的数组、变量可以是以下类型:整数、实数、字符、位串或指针。通常这些类型可以从算法的上下文来看是清楚的,并不需要额外加以说明。 2) 在算法中的某些指令或子任务可以用文字来叙述,例如,"设x是A中的最大项",这里A是一个数组;或者"将x插入L中",这里L是一个链表。这样做的目的是为了避免因那些与主要问题无关的细节使算法本身杂乱无章。 3) 算术表达式可以使用通常的算术运算符(+,-,*,/,以及表示幂的^)。逻辑表达式可以使用关系运算符=,≠,<,>,≤和≥,以及逻辑运算符与(and),或(or),非(not)。 4) 赋值语句是如下形式的语句:a<-b 。 这里a是变量、数组项,b是算术表达式、逻辑表达式或指针表达式。语句的含义是将b的值赋给a。 5) 若a和b都是变量、数组项,那么记号a<->b 表示a和b的内容进行交换。 var int[64] r, k //r specifies the per-round shift amounts r[ 0..15]:= {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22} r[16..31]:= {5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20} r[32..47]:= {4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23} r[48..63]:= {6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21} //Use binary integer part of the sines of integers as constants: for i from 0 to 63 k[i] := floor(abs(sin(i + 1)) × 2^32) //Initialize variables: var int h0 := 0x67452301 var int h1 := 0xEFCDAB89 var int h2 := 0x98BADCFE var int h3 := 0x10325476 //Pre-processing: append "1" bit to message append "0" bits until message length in bits ≡ 448 (mod 512) append bit length of message as 64-bit little-endian integer to message //Process the message in successive 512-bit chunks: for each 512-bit chunk of message break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15 //Initialize hash value for this chunk: var int a := h0 var int b := h1 var int c := h2 var int d := h3 //Main loop: for i from 0 to 63 if 0 ≤ i ≤ 15 then f := (b and c) or ((not b) and d) g := i else if 16 ≤ i ≤ 31 f := (d and b) or ((not d) and c)算法设计及分析递归算法典型例题
伪代码
算法设计与分析考试题及答案
算法设计与分析
4.29 算法伪代码练习讲义
《算法概论》-伪代码
算法设计与分析学习总结
算法设计与分析基础习题参考答案
算法设计与分析的经典问题
伪代码的使用规范
计算机算法设计与分析课程设计
算法设计与分析(简略版)
遗传算法解释及代码(一看就懂)
伪代码定义及实例
伪代码及其实例讲解
MD5算法的伪代码
算法设计及的分析部分算法伪代码