首页 > 编程知识 正文

计算机算法设计与分析期末考试题,算法设计与分析第四版电子书

时间:2023-05-03 21:29:59 阅读:149411 作者:2200

算法概述1.1算法和程序算法是由几个指令组成的穷举序列,满足以下四个性质:

(1)输入)作为算法的输入,外部给定的量有零个以上。

(2)输出)算法生成至少一个量作为输出。

(3)确定性:构成算法的各命令清晰,无歧义。

(4)有限性:算法中每条指令的执行次数有限,每条指令的执行时间也有限。

问题:由输入和输出的关系定义

算法:将问题输入转换为输出的计算过程

程序:用编程语言实现算法

程序时算法的计算机高级描述,是算法的具体实现;算法更可看成是程序的灵魂。程序可以不满足算法性质的第四条有限性。

*

有几种方法可以描述算法。

自然语言方式、表方式、图形形式等

C和自然语言相结合的方式

数据结构是算法的基础

算法确定如何构建数据

算法和数据结构等于程序

*算法设计的一般步骤:

1 .分析问题,建立数学模型

2 .梳理相关已知知识,分解问题

3 .设计算法,建立初步解

4 .对设计的算法进行正确性证明

5 .有效分析正确的算法

6 .用程序实现分析后的算法

7 .相关文档的完善。

空间复杂性:

考虑空间复杂性的理由:

在多用户系统上运行时,必须指定分配给程序的内存大小。

我想事先知道计算机系统是否有足够的内存运行程序

一个问题可能有几种不同的内存要求解决方案。 从其中选择。

用空间复杂度估计一个程序可以解决的问题的最大规模。

程序与算法不同,是用某种编程语言具体实现算法的,程序可以不满足算法的性质(4)。

描述算法有自然语言方式、表示方式等各种方式。

算法复杂性的高低体现在运行该算法所需的计算机资源的多寡上,所需资源越多,该算法的复杂性就越高;相反,所需资源越少,算法的复杂性就越低。 对于计算机资源来说,最重要的是时间和空间,即存储资源。 因此,算法的复杂度既有时间复杂度,也有空间复杂度。

算法的复杂性是指执行算法所需的计算机资源的量,需要时间资源的量称为时间复杂性,需要空间资源的量称为空间复杂性。 这个量应该集中反映算法的效率,并从运行该算法的实际计算机中抽象出来。 换句话说,这个量应该是依赖于要解决的问题的规模、算法的输入和算法本身的函数。

算法求解问题的规模、算法的输入、算法本身分别用n、I、a表示,且复杂度用c表示,则有c=f(n,I,a )。 这里,f ) n,I,a )是由n,I,a确定的三元函数。 时间复杂性t=t(n,I,a )和s=s (n,I,a )。 通常,a隐藏在复杂性函数名中,所以将t和s分别简称为t=t(n,I )和s=s ) n,I )。

累进符号

以下讨论用f(n )表示一个程序的时间或空间复杂度。 这是实例特征n (一般为输入范围)的函数。

由于程序的时间或空间要求为非负实数,因此也可以假设函数f(n )对于n的所有值为非负实数,并假设n=0

渐进码o的定义:存在正数常数c和自然数N0,使得当n大于等于N0时f(n )小于等于CG ) n,g ) n为函数f ) n的一个上界,f(n )=o ) g(n ),即f(n )的阶数为g )。

用于比较的函数g(n )应该尽可能接近所考虑的函数f ) n )

递归和分治策略直接或间接调用自身的算法称为递归算法。 由函数本身给出定义的函数称为递归函数。 分治法产生的子问题往往是原问题的小模式,便于使用递归技术。 在这种情况下,通过反复应用分治的方法,可以使原问题和子问题的类型一致,但其规模继续缩小,最终可以缩小到容易直接求出其解的程度。 这自然会导致递归过程的发生。

分治和递归像孪生兄弟,往往同时应用于算法设计,从而产生许多高效算法。

阶乘函数阶乘函数可以递归定义

边界条件和递归方程是递归函数的两个要素,递归函数只有具备这两个要求,才能在有限次计算后得出结果。

Fibonacci数列

intFibonacci(intn ) if (n=1) return 1; returnFibonacci(n-1 ) Fibonacci (n-2 ); } Ackerman函数

如果函数及其变量是由函数本身定义的,则该函数称为双重递归函数。

Ackerman函数a(n,m )是a (1,0 )=2,a ) 0,m )=1,a ) n,0 )=(N2 ) n=2,a ) n,m ) ) n-1,m

罗列问题

设计递归算法生成n个要素{r1,r2,rn}的全排列。

# includeiostreamusingnamespacestd; void P

erm(int list[],int k,int m){if(k == m){for(int i=0;i<=m;i++) cout<<list[i];cout<<endl;}else{for(int i=k;i<=m;i++){swap(list[k],list[i]);Perm(list,k+1,m);swap(list[k],list[i]);}}}void swap(int &a,int &b){int temp = a;a = b;b = temp;} int main(){int a[3] = {1,2,3};Perm(a,0,2);return 0; }

整数划分问题
将正整数n表示成一系列之和,n=n1+n2+n3…+nn
可建立q(n,m)的如下递归关系。

代码实现

int q(int n,int m){if((n < 1)||(m<1)) return 0; else if(n == 1 || m == 1) return 1;else if(n < m) return q(n,n);else if(n == m) return 1 + q(n,n-1);else return q(n,m-1) +q(n-m,m);}

Hanoi塔问题

void hanio(int n ,int a,int b,int c ){if(n>0){hanio(n-1,a,c,b);move(a,b);hanio(n-1.c,b,a);}}

递归小结
优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大的方便。
缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

在具体处理过程中存在明显的不同:递归方法是采用自顶向下的方式产生计算序列,这个过程可能导致许多重复的调用,这也是递归算法效率较低的主要原因之一;而递推采用自底向上的方式产生计算序列,使每一步新产生的计算结果总是建立子啊已有结果的基础上,避免了许多重复的计算。利用子问题已有的解构造规模较大子问题的解,进而构造原问题的解,因而比递归算法具有更高的效率。

分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相会独立且与原问题相同。递归地解这些子问题,然后将各子问题的解合并得到原来的解。

分治法的基本步骤:(1)分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
(2)解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题。
(3)合并:将各个子问题的解合并为原问题的解。

分治法所能解决的问题一般具有以下几个特征:
该问题的规模缩小到一定的程度就可以容易地解决;
该问题可以分解为若干个规模较小的相同问题;
利用该问题分解出的子问题的解可以合并为该问题的解;
该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。

二分搜索技术

int BinarySearch(Type a[],Type const& x,int n){int left = 0;int right = n-1;while(left <= right){int middle = (left + right)/2;if(x == a[middle]) return middle;if(x > a[middle]) left = middle + 1;else right = middle - 1;}return - 1;}

大整数的乘法
设计一个有效的算法,求两个n位二进制大整数的乘积

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。