数据结构与算法-算法设计与分析.ppt
《数据结构与算法-算法设计与分析.ppt》由会员分享,可在线阅读,更多相关《数据结构与算法-算法设计与分析.ppt(356页珍藏版)》请在三一办公上搜索。
1、1,中国计算机学会“21世纪大学本科计算机专业系列教材”算法设计与分析,王晓东编著,2,主要内容介绍,第1章算法引论第2章递归与分治策略第3章动态规划第4章贪心算法第5章回溯法第6章分支限界法,3,主要内容介绍(续),第7章概率算法第8章NP完全性理论第9章近似算法第10章算法优化策略,4,第1章 算法引论,1.1算法与程序1.2表达算法的抽象机制1.3描述算法1.4算法复杂性分析,本章主要知识点:,5,1.1算法与程序,输 入:有零个或多个外部量作为算法的输入。输 出:算法产生至少一个量作为输出。确定性:组成算法的每条指令清晰、无歧义。有限性:算法中每条指令的执行次数有限,执行每条指令的时间
2、也有限。,是算法用某种程序设计语言的具体实现。程序可以不满足算法的性质(4)即有限性。,是满足下述性质的指令序列。,算法:,程序:,6,1.从机器语言到高级语言的抽象,1.2表达算法的抽象机制,高级程序设计语言的主要好处是:,(4)把繁杂琐碎的事务交给编译程序,所以自动化程度高,开发周期短,程序员可以集中时间和精力从事更重要的创造性劳动,提高程序质量。,(1)高级语言更接近算法语言,易学、易掌握,一般工程技术人员只需 要几周时间的培训就可以胜任程序员的工作;,(2)高级语言为程序员提供了结构化程序设计的环境和工具,使得设计出来的程序可读性好,可维护性强,可靠性高;,(3)高级语言不依赖于机器语
3、言,与具体的计算机硬件关系不大,因而所写出来的程序可植性好、重用率高;,7,2.抽象数据类型,1.2表达算法的抽象机制,抽象数据类型是算法的一个数据模型连同定义在该模型上并作为算法构件的一组运算。,抽象数据类型带给算法设计的好处有:,(1)算法顶层设计与底层实现分离;(2)算法设计与数据结构设计隔开,允许数据结构自由选择;(3)数据模型和该模型上的运算统一在ADT中,便于空间和时间耗费的折衷;(4)用抽象数据类型表述的算法具有很好的可维护性;(5)算法自然呈现模块化;(6)为自顶向下逐步求精和模块化提供有效途径和工具;(7)算法结构清晰,层次分明,便于算法正确性的证明和复杂性的分析。,8,在本
4、书中,采用Java语言描述算法。1.Java程序结构,1.3描述算法,以下,对Java语言的若干重要特性作简要概述。,(1)Java程序的两种类型:应用程序和applet区别:应用程序的主方法为main,其可在命令行中用命令语句 java 应用程序名 来执行;applet的主方法为init,其必须嵌入HTML文件,由Web浏览器或applet阅读器来执行。,(2)包:java程序和类可以包(packages)的形式组织管理。,(3)import语句:在java程序中可用import语句加载所需的包。例如,import java.io.*;语句加载java.io包。,9,1.3描述算法,2.Ja
5、va数据类型,Java对两种数据类型的不同处理方式:,s=new String(“Welcome”);String s=new String(“Welcome”);,10,1.3描述算法,表格1-1 Java基本数据类型,11,1.3描述算法,3.方法,在Java中,执行特定任务的函数或过程统称为方法(methods)。例如,java的Math类给出的常见数学计算的方法如下表所示:,12,1.3描述算法,3.方法,计算表达式 值的自定义方法ab描述如下:,public static int ab(int a,int b)return(a+b+Math.abs(a-b)/2;,(1)方法参数:J
6、ava中所有方法的参数均为值参数。上述方法ab中,a和b是形式参数,在调用方法时通过实际参数赋值。,(2)方法重载:Java允许方法重载,即允许定义有不同签名的同名方法。上述方法ab可重载为:,public static double ab(double a,double b)return(a+b+Math.abs(a-b)/2.0;,13,1.3描述算法,4.异常,Java的异常提供了一种处理错误的方法。当程序发现一个错误,就引发一个异常,以便在合适地方捕获异常并进行处理。,通常用try块来定义异常处理。每个异常处理由一个catch语句组成。,public static void main(
7、String args)try f();catch(exception1)异常处理;catch(exception2)异常处理;finally finally块;,14,1.3描述算法,5.Java的类,(4)访问修饰,Java的类一般由4个部分组成:,(1)类名,(2)数据成员,(3)方法,15,1.3描述算法,6.通用方法,下面的方法swap用于交换一维整型数组a的位置i和位置j处的值。,public static void swap(int a,int i,int j)int temp=ai;ai=aj;aj=temp;,public static void swap(object a,
8、int i,int j)object temp=ai;ai=aj;aj=temp;,该方法只适用于整型数组,该方法具有通用性,适用于Object类型及其所有子类,以上方法修改如下:,16,1.3描述算法,6.通用方法,(1)Computable界面,public static Computable sum(Computable a,int n)if(a.length=0)return null;Computable sum=(Computable)a0.zero();for(int i=0;i n;i+)sum.increment(ai);return sum;,利用此界面使方法sum通用化,
9、17,1.3描述算法,6.通用方法,(2)java.lang.Comparable 界面,Java的Comparable 界面中惟一的方法头compareTo用于比较2个元素的大小。例如java.lang.CpareTo(y)返回x-y的符号,当xy时返回正数。,(3)Operable 界面,有些通用方法同时需要Computable界面和Comparable 界面的支持。为此可定义Operable界面如下:,public interface Operable extends Computable,Comparable,(4)自定义包装类,由于Java的包装类如Integer等已定义为final
10、型,因此无法定义其子类,作进一步扩充。为了需要可自定义包装类。,18,1.3描述算法,7.垃圾收集8.递归,Java的new运算用于分配所需的内存空间。例如,int a=new int500000;分配2000000字节空间给整型数组a。频繁用new分配空间可能会耗尽内存。Java的垃圾收集器会适时扫描内存,回收不用的空间(垃圾)给new重新分配。,Java允许方法调用其自身。这类方法称为递归方法。,public static int sum(int a,int n)if(n=0)return 0;else return an-1+sum(a,n-1);,计算一维整型数组前n个元素之和的递归方
11、法,19,1.4算法复杂性分析,算法复杂性是算法运行所需要的计算机资源的量,需要时间资源的量称为时间复杂性,需要的空间资源的量称为空间复杂性。这个量应该只依赖于算法要解的问题的规模、算法的输入和算法本身的函数。如果分别用N、I和A表示算法要解问题的规模、算法的输入和算法本身,而且用C表示复杂性,那么,应该有C=F(N,I,A)。一般把时间复杂性和空间复杂性分开,并分别用T和S来表示,则有:T=T(N,I)和S=S(N,I)。(通常,让A隐含在复杂性函数名当中),20,1.4算法复杂性分析,最坏情况下的时间复杂性:,最好情况下的时间复杂性:,平均情况下的时间复杂性:,其中DN是规模为N的合法输入
12、的集合;I*是DN中使T(N,I*)达到Tmax(N)的合法输入;是中使T(N,)达到Tmin(N)的合法输入;而P(I)是在算法的应用中出现输入I的概率。,21,1.4算法复杂性分析,算法复杂性在渐近意义下的阶:,渐近意义下的记号:O、o 设f(N)和g(N)是定义在正数集上的正函数。,O的定义:如果存在正的常数C和自然数N0,使得当NN0时有f(N)Cg(N),则称函数f(N)当N充分大时上有界,且g(N)是它的一个上界,记为f(N)=O(g(N)。即f(N)的阶不高于g(N)的阶。,根据O的定义,容易证明它有如下运算规则:(1)O(f)+O(g)=O(max(f,g);(2)O(f)+O
13、(g)=O(f+g);(3)O(f)O(g)=O(fg);(4)如果g(N)=O(f(N),则O(f)+O(g)=O(f);(5)O(Cf(N)=O(f(N),其中C是一个正的常数;(6)f=O(f)。,22,1.4算法复杂性分析,的定义:如果存在正的常数C和自然数N0,使得当NN0时有f(N)Cg(N),则称函数f(N)当N充分大时下有界,且g(N)是它的一个下界,记为f(N)=(g(N)。即f(N)的阶不低于g(N)的阶。,的定义:定义f(N)=(g(N)当且仅当f(N)=O(g(N)且f(N)=(g(N)。此时称f(N)与g(N)同阶。,o的定义:对于任意给定的0,都存在正整数N0,使得
14、当NN0时有f(N)/Cg(N),则称函数f(N)当N充分大时的阶比g(N)低,记为f(N)=o(g(N)。例如,4NlogN+7=o(3N2+4NlogN+7)。,23,第2章 递归与分治策略,24,将要求解的较大规模的问题分割成k个更小规模的子问题。,算法总体思想,n,T(n/2),T(n/2),T(n/2),T(n/2),T(n),=,对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。,25,算法总体思想,对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问
15、题规模足够小,很容易求出其解为止。,n,T(n),=,将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。,26,算法总体思想,将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。,n,T(n),=,27,算法总体思想,将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。,分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。凡治众如治寡,分数是也。-孙子兵法,28,2.1 递归的概念,直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称
16、为递归函数。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。,下面来看几个实例。,29,2.1 递归的概念,例1 阶乘函数阶乘函数可递归地定义为:,边界条件,递归方程,边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果。,30,2.1 递归的概念,例2 Fibonacci数列无穷数列1,1,2,3,5,8
17、,13,21,34,55,被称为Fibonacci数列。它可以递归地定义为:,边界条件,递归方程,第n个Fibonacci数可递归地计算如下:public static int fibonacci(int n)if(n=1)return 1;return fibonacci(n-1)+fibonacci(n-2);,31,32,2.1 递归的概念,例3 Ackerman函数当一个函数及它的一个变量是由函数自身定义时,称这个函数是双递归函数。Ackerman函数A(n,m)定义如下:,33,2.1 递归的概念,例3 Ackerman函数前2例中的函数都可以找到相应的非递归方式定义:,但本例中的A
18、ckerman函数却无法找到非递归的定义。,34,2.1 递归的概念,例3 Ackerman函数A(n,m)的自变量m的每一个值都定义了一个单变量函数:M=0时,A(n,0)=n+2M=1时,A(n,1)=A(A(n-1,1),0)=A(n-1,1)+2,和A(1,1)=2故A(n,1)=2*nM=2时,A(n,2)=A(A(n-1,2),1)=2A(n-1,2),和A(1,2)=A(A(0,2),1)=A(1,1)=2,故A(n,2)=2n。M=3时,类似的可以推出M=4时,A(n,4)的增长速度非常快,以至于没有适当的数学式子来表示这一函数。,35,2.1 递归的概念,例3 Ackerma
19、n函数定义单变量的Ackerman函数A(n)为,A(n)=A(n,n)。定义其拟逆函数(n)为:(n)=minkA(k)n。即(n)是使nA(k)成立的最小的k值。(n)在复杂度分析中常遇到。对于通常所见到的正整数n,有(n)4。但在理论上(n)没有上界,随着n的增加,它以难以想象的慢速度趋向正无穷大。,36,2.1 递归的概念,例4 排列问题设计一个递归算法生成n个元素r1,r2,rn的全排列。,设R=r1,r2,rn是要进行排列的n个元素,Ri=R-ri。集合X中元素的全排列记为perm(X)。(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。R的全排列可
20、归纳定义如下:,当n=1时,perm(R)=(r),其中r是集合R中唯一的元素;当n1时,perm(R)由(r1)perm(R1),(r2)perm(R2),(rn)perm(Rn)构成。,37,2.1 递归的概念,例5 整数划分问题将正整数n表示成一系列正整数之和:n=n1+n2+nk,其中n1n2nk1,k1。正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。例如正整数6有如下11种不同的划分:6;5+1;4+2,4+1+1;3+3,3+2+1,3+1+1+1;2+2+2,2+2+1+1,2+1+1+1+1;1+1+1+1+1+1。,38,(2)q(n,m)=q(n,n),m
21、n;最大加数n1实际上不能大于n。因此,q(1,m)=1。,(1)q(n,1)=1,n1;当最大加数n1不大于1时,任何正整数n只有一种划分形式,即,(4)q(n,m)=q(n,m-1)+q(n-m,m),nm1;正整数n的最大加数n1不大于m的划分由n1=m的划分和n1n-1 的划分组成。,(3)q(n,n)=1+q(n,n-1);正整数n的划分由n1=n的划分和n1n-1的划分组成。,2.1 递归的概念,例5 整数划分问题前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将
22、最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。,39,2.1 递归的概念,例5 整数划分问题前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。,正整数n的划分数p(n)=q(n,n)。,40,41,2.1 递归的概念,例6 Hanoi塔问题设a,b,c是3个塔座。开始时,在塔座a上有一叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为
23、1,2,n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则:规则1:每次只能移动1个圆盘;规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;规则3:在满足移动规则1和2的前提下,可将圆盘移至a,b,c中任一塔座上。,42,在问题规模较大时,较难找到一般的方法,因此我们尝试用递归技术来解决这个问题。,当n=1时,问题比较简单。此时,只要将编号为1的圆盘从塔座a直接移至塔座b上即可。当n1时,需要利用塔座c作为辅助塔座。此时若能设法将n-1个较小的圆盘依照移动规则从塔座a移至塔座c,然后,将剩下的最大圆盘从塔座a移至塔座b,最后,再设法将n-1个
24、较小的圆盘依照移动规则从塔座c移至塔座b。由此可见,n个圆盘的移动问题可分为2次n-1个圆盘的移动问题,这又可以递归地用上述方法来做。由此可以设计出解Hanoi塔问题的递归算法如下。,2.1 递归的概念,例6 Hanoi塔问题,public static void hanoi(int n,int a,int b,int c)if(n 0)hanoi(n-1,a,c,b);move(a,b);hanoi(n-1,c,b,a);,思考题:如果塔的个数变为a,b,c,d四个,现要将n个圆盘从a全部移动到d,移动规则不变,求移动步数最小的方案。,43,递归小结,优点:结构清晰,可读性强,而且容易用数学
25、归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。,44,递归小结,解决方法:在递归算法中消除递归调用,使其转化为非递归算法。1.采用一个用户定义的栈来模拟系统的递归调用工作栈。该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。2.用递推来实现递归函数。3.通过Cooper变换、反演变换能将一些递归转化为尾递归,从而迭代求出结果。后两种方法在时空复杂度上均有较大改善,但其适用范围有限。,45,分治法的适用条件,分治法所能解决的问题一般具有以下几个特征:该问
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 算法 设计 分析
链接地址:https://www.31ppt.com/p-6296830.html