算法复杂度——时间复杂度和空间复杂度

合集下载

复习提纲:算法与数据结构

复习提纲:算法与数据结构

1、算法的概念是为了解决某类问题而规定的一个有限长的操作序列。

特性:①有穷性②确定性③可行性④输入⑤输出评价标准:①正确性②可读性③健壮性④高效性2、算法的复杂度: 算法计算量所需资源的大小时间复杂度:T(n)=O(f(n)),他表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的时间复杂度空间复杂度:S(n)=O(f(n)),算法所需空间的度量。

3、数据结构中的逻辑结构分为:线性和非线性结构4、线性表的两种存储方式:顺序存储和链式存储的特点及比较。

顺序存储:指用一组地址连续的存储单元依次存储线性表的数据元素链式存储:用一组任意的存储单元存储线性表的数据元素。

5、线性表的特点①存在唯一的一个被称作“第一个”的数据元素②存在唯一的一个被称作“最后一个”的数据元素③除第一个之外,结构中的每一个数据元素均只有一个前驱④除最后一个之外,结构中的每一个数据元素均只有一个后继6、在长度为n的顺序表中的第i个位置处插入一个元素,需要移动多少个元素?n-i+17、理解算法:线性表La和Lb,将两个表合并成一个新的线性表并存于La中。

8、带头结点的单链表和不带头结点的单链表为空的条件分别是?带头结点的循环单链表为空的条件是?带头结点的单链表为空的条件:没有下一个节点L->next=NULL不带头结点的单链表为空的条件:L=NULL循环单链表为空的条件:head->next=head带头结点的循环单链表为空的条件是9、在单链表中插入结点的算法中,指针如何修改。

P3410、理解单链表中插入新结点的算法p3411、理解双向链表中插入新结点的算法p4012、理解栈和队列的操作特点:先进后出,先进先出。

已知进栈顺序,求可能的出栈顺序。

链栈相对于顺序栈的优点是什么?链栈在入栈前不需要判断栈是否为满,只需要为入栈元素动态分配一个节点空间13、理解算法:执行进栈操作,则先要判断栈S是否为满,若不满再将记录栈顶的下标变量top加1,再将进栈元素放进栈顶位置上。

大学计算机基础算法

大学计算机基础算法

《大学计算机基础》 主讲人:赵丕锡教授
8.2.1 什么是数据结构?
例8.5 无序表的顺序查找与有序表的对分查找。
《大学计算机基础》 主讲人:赵丕锡教授
现实世界中存在的一切个体都可以是数据元素。
例如:“春、夏、秋、冬”,可以作为季节的数据元素;
“26、56、65、 73、26、…”,可以作为数值的数据元素;
《大学计算机基础》
第8章 数据结构与算法
程序是什么?
程序=数据结构+算法!
大连民族学院计算机学院 赵丕锡教授
例:某校对100个学生进行奖励,学生信息存在磁盘文件“file.dat”中, 条件是其三门成绩全部在90分以上才能进行奖励,打印出被奖励学生 的学号。
以C语言为例,程序代码如下: #include <stdio.h> Void main() { struct stu /*数据类型*/ { int num; float score[3]; }a[100]; /* 定义变量*/ FILE *fp; Int I,j; fp=fopen(“file.dat”,”r”); /* 打开文件file.dat*/
对操作的描述。即对数据的操作处理步骤。
程序:就是用计算机语言表示的数据结构和算法。 程序设计:用计算机语言编写程序的过程。两个基本步骤: 1、设计数据结构和算法。 2、用一种计算机语言表示出来。
因此,数据结构与算法是程序设计的基础。
《大学计算机基础》 主讲人:赵丕锡教授
8.1 算

8.1.1 算法的基本概念
首先计算区间的中点c=(a+b)/2,然后计算函数在中点c的值f (c),并判断f (c)是否为0。若f(c)=0,则说明c就是所求的根, 求解过程结束;如果f (c)≠0,则根据以下原则将原区间减半:

十大经典排序算法总结

十大经典排序算法总结

⼗⼤经典排序算法总结最近⼏天在研究算法,将⼏种排序算法整理了⼀下,便于对这些排序算法进⾏⽐较,若有错误的地⽅,还请⼤家指正0、排序算法说明0.1 排序术语稳定:如果a=b,且a原本排在b前⾯,排序之后a仍排在b的前⾯不稳定:如果a=b,且a原本排在b前⾯,排序之后排在b的后⾯时间复杂度:⼀个算法执⾏所耗费的时间空间复杂度:⼀个算法执⾏完所需内存的⼤⼩内排序:所有排序操作都在内存中完成外排序:由于数据太⼤,因此把数据放在磁盘中,⽽排序通过磁盘和内存的数据传输才能进⾏0.2算法时间复杂度、空间复杂度⽐较0.3名词解释n:数据规模k:桶的个数In-place:占⽤常数内存,不占⽤额外内存Out-place:占⽤额外内存0.4算法分类1.冒泡排序冒泡排序是⼀种简单的排序算法。

它重复地⾛访过要排序的数列,⼀次⽐较两个元素,如果它们的顺序错误就把它们交换过来。

⾛访数列的⼯作是重复地进⾏直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越⼩的元素会经由交换慢慢“浮”到数列的顶端1.1算法描述⽐较相邻的元素,如果前⼀个⽐后⼀个打,就交换对每⼀对相邻元素做同样的⼯作,从开始第⼀对到结尾最后⼀对,这样在最后的元素应该会是最⼤的数针对所有的元素重复以上的步骤,除了最后⼀个重复步骤1-3,知道排序完成1.2动图演⽰1.3代码实现public static int[] bubbleSort(int[] array) {if (array.length == 0)return array;for (int i = 0; i < array.length; i++)for (int j = 0; j < array.length - 1 - i; j++)if (array[j + 1] < array[j]) {int temp = array[j + 1];array[j + 1] = array[j];array[j] = temp;}return array;}1.4算法分析最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)2.选择排序表现简单直观的最稳定的排序算法之⼀,因为⽆论什么数据都是O(n2)的时间复杂度,⾸先在未排序序列中找到最⼩(⼤)元素,与数组中第⼀个元素交换位置,作为排序序列的起始位置,然后再从剩余未排序元素中继续寻找最⼩(⼤)的元素,与数组中的下⼀个元素交换位置,也就是放在已排序序列的末尾2.1算法描述1.初始状态:⽆序区为R[1..n],有序区为空2.第i躺排序开始时,当前有序区和⽆序区R[1..i-1]、R[i..n]3.n-1趟结束,数组有序化2.2动图演⽰2.3代码实现public static int[] selectionSort(int[] array) {if (array.length == 0)return array;for (int i = 0; i < array.length; i++) {int minIndex = i;for (int j = i; j < array.length; j++) {if (array[j] < array[minIndex]) //找到最⼩的数minIndex = j; //将最⼩数的索引保存}int temp = array[minIndex];array[minIndex] = array[i];array[i] = temp;}return array;}2.4算法分析最佳情况:T(n) = O(n2) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)3、插⼊排序是⼀种简单直观的排序算法,通过构建有序序列,对于未排序序列,在已排序序列中从后向前扫描,找到相应位置并插⼊,需要反复把已排序元素逐步向后挪位,为最新元素腾出插⼊空间3.1算法描述1.从第⼀个元素开始,该元素可以认为已经被排序2.取出下⼀个元素(h),在已排序的元素序列中从后往前扫描3.如果当前元素⼤于h,将当前元素移到下⼀位置4.重复步骤3,直到找到已排序的元素⼩于等于h的位置5.将h插⼊到该位置6.重复步骤2-53.2动图演⽰3.3代码实现public static int[] insertionSort(int[] array) {if (array.length == 0)return array;int current;for (int i = 0; i < array.length - 1; i++) {current = array[i + 1];int preIndex = i;while (preIndex >= 0 && current < array[preIndex]) {array[preIndex + 1] = array[preIndex];preIndex--;}array[preIndex + 1] = current;}return array;}3.4算法分析最佳情况:T(n) = O(n) 最坏情况:T(n) = O(n2) 平均情况:T(n) = O(n2)4、希尔排序是简单插⼊排序经过改进之后的⼀个更⾼效的版本,也称为缩⼩增量排序,同时该算法是冲破O(n2)的第⼀批算法之⼀。

matlab 时间空间复杂度计算

matlab 时间空间复杂度计算

matlab 时间空间复杂度计算在计算机科学中,时间复杂度和空间复杂度是评估算法性能的两个重要指标。

而在MATLAB中,对于算法的时间复杂度和空间复杂度的计算与其他编程语言类似。

本文将从理论和实际应用的角度,详细介绍MATLAB中时间复杂度和空间复杂度的计算方法,并探讨如何优化算法以提高性能。

时间复杂度是衡量算法执行时间随输入规模增长而增长的程度,通常用大O符号表示。

它描述了算法执行所需的基本操作次数,并提供了一种粗略的估计。

在MATLAB中,我们可以使用复杂度符号库来计算时间复杂度。

常见的时间复杂度包括:-常数时间复杂度O(1):算法的执行时间不受输入规模的影响,例如直接访问数组元素。

-线性时间复杂度O(n):算法的执行时间与输入规模n成正比,例如遍历数组或链表。

-对数时间复杂度O(log n):算法的执行时间随输入规模n的对数增加,例如二分查找。

-平方时间复杂度O(n^2):算法的执行时间与输入规模n的平方成正比,例如嵌套循环。

在MATLAB中,可以通过分析循环、递归和函数的调用来判断算法的时间复杂度。

具体方法如下:1.计算循环次数:分析算法中的循环结构,找出循环变量的变化规律并计算循环次数。

通常情况下,循环结构的复杂度与循环次数成正比。

2.分析递归调用:递归算法的时间复杂度可以通过递归树来计算。

根据递推关系式和递归调用的次数,可以得到递归算法的复杂度。

3.考虑函数调用开销:函数调用也会耗费一定的时间,特别是输入和输出参数的传递。

因此,在计算算法复杂度时,需要考虑函数调用的开销。

空间复杂度是衡量算法在执行过程中所需的额外内存空间的大小,通常也用大O符号表示。

它描述了算法所需的内存空间随输入规模增长而增加的程度。

常见的空间复杂度包括:-常数空间复杂度O(1):算法所需的额外内存空间是固定的,与输入规模无关,例如只使用有限个额外变量。

-线性空间复杂度O(n):算法所需的额外内存空间与输入规模n成正比,例如需要创建一个与输入规模相同大小的数组来存储数据。

概率多项式时间

概率多项式时间

概率多项式时间在密码学中,经常需要评估算法的时间复杂度,掌握相关知识。

上一篇文章中提到的概率多项式时间图灵机,这里也要解释一下。

1.算法效率的评估方法:算法的效率主要由以下两个复杂度来评估:时间复杂度:评估执行程序所需的时间。

空间复杂度:评估执行程序所需的内存空间。

时间复杂度是指随着问题规模的扩大,解决一个问题所需时间的增长率。

一般来说,时间复杂度比空间复杂度更难解决,算法研究的主要焦点是时间复杂度。

除非特别说明,复杂度是指时间复杂度。

2.时间复杂度概率多项式时间 4多项式时间指的是一个算法的复杂度,在时间复杂度的计算中常用的时间复杂度按照耗费的时间从小到大依次是:O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!)。

只要算法的复杂度不会是最后两个指数或者阶乘型,前面的O(1)到O(n^m)(m为常数)任意组合都算是多项式级的复杂度,它们的规模n都出现在底数位置;而O(2ⁿ),O(n!)型复杂度,就是非多项式级的,问题规模较大时,计算机也很难算出结果。

所以我们一般会选择多项式级复杂度的算法。

4.确定性与概率性如果同一个问题你解决两次,得到的答案是一样的,那就叫确定性,如果答案可能不一样,那就叫概率。

比如两次输入1,如果两次输出都是2,那么就是确定性的;如果两个输出是2,3,或者其他答案,那就是概率性的。

5.P问题与NP问题(这里的P是指Polynomial,即多项式)P问题:只要问题存在确定性多项式级复杂度的解决算法,就称之为P问题。

(比较好算)NP问题:不存在确定性多项式级复杂度的解决算法,但是存在多项式时间的算法来验证某个答案是否正确,就称之为NP 问题。

(不好算,但是对给出的答案可以很快的验证对不对)还有NPC问题,有兴趣自己查一下。

很明显,P问题是包含于NP问题的,但P是否等于NP,即P=NP,是一个尚无法证明的问题。

空间复杂度怎么算

空间复杂度怎么算

空间复杂度怎么算1.算法效率算法分析有两种:第一种是时间效率,第二种是空间效率。

时间效率叫时间复杂度,空间效率叫空间复杂度。

时间复杂度主要衡量一个算法的运行速度,空间复杂度主要衡量一个算法需要的额外空间。

在计算机发展的早期,计算机的存储容量非常小。

所以我非常关心空间的复杂性。

然而,随着计算机行业的快速发展,计算机的存储容量已经达到了很高的水平。

所以现在我们不需要特别关注一个算法的空间复杂度。

2.时间复杂度2.1时间复杂度的概念时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数(数学中表达式未知的函数),定量描述算法的运行时间。

理论上,一个算法执行的时间是无法计算的。

只有把你的程序放到机器上运行,你才能知道。

但是我们需要在电脑上测试每一个算法吗?可以在电脑上测试,但是很麻烦,于是就有了时间复杂度分析法。

算法花费的时间与其语句的执行次数成正比,算法中基本运算的执行次数就是算法的时间复杂度。

3.空间复杂度空间复杂度是对一个算法在运行过程中临时占用存储空间大小量度。

空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。

空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

4.大O渐进表示法•大O符号(Big O notation):是用于描述函数渐进行为的数学符号。

推导大O阶方法:• 1.用常数1替换运行时的所有加法常数。

• 2.在操作次数的修正函数中,只保留最高阶项。

•3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。

得到的结果就是大O阶。

另外有些算法的时间复杂度存在最好、平均和最坏情况:•最坏情况:任意输入规模的最大运行次数(上界) 平均情况:任意输入规模的期望运行次数•最好情况:任意输入规模的最小运行次数(下界) 例如:在一个长度为N数组中搜索一个数据x 最好情况:1次找到最坏情况:N次找到•平均情况:N/2次找到在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)5.常见时间复杂度计算一下这个算法的时间复杂度// 请计算一下Func1基本操作执行了多少次?voidFunc1(intN){intcount=0;//两层循环嵌套外循环执行n 次,内循环执行n次,整体计算就是N*N的执行次数for(inti=0;i<N;++i){for(intj=0;j<N;++j){++count;}}//2 * N的执行次数for(intk=0;k<2*N;++k){++count;}//常数项10intM=10;while(M--){++count;}printf("%d\n",count);}精确的时间复杂度是N ^ 2 + 2 * N + 10 大O的渐进表示法时间复杂度是O(N ^ 2) 分析: 1、两层循环嵌套外循环执行n次,内循环执行n次,整体计算就是N*N 的执行次数 2、2 * N的执行次数 3、常数项10 根据前面的大o渐进表示法规则,所以最后只保留那项对执行次数影响最大的那一项,时间复杂度就是O(N ^ 2)。

迪杰斯特拉算法复杂度

迪杰斯特拉算法复杂度

迪杰斯特拉算法复杂度迪杰斯特拉算法是一种用于在有向图中找出单源最短路径的算法。

它的主要思想是以起始点为中心,每次寻找到起始点距离最近的一个点,将其加到已找到最短路径的集合中,然后更新距离,这样便可以不断推出起始点的最短路径,直至终点。

1、迪杰斯特拉算法概述:迪杰斯特拉算法是一种最优化算法,它的主要应用场景是求出一条从源点到各点的最短路径。

迪杰斯特拉算法不仅可以解决最短路径问题,还能解决优化问题、背包问题、旅行推销员问题、分配资源最佳决策问题等8类问题。

2、迪杰斯特拉算法步骤:(1)从起点出发,依次将未经评估的任一点作为当前点,求出从起点到该点的距离(即Astar算法的f值),记录起点到该点的路径;(2)从当前点出发,求出从这个点开始到其余任一未经评估的点的距离,更新起点到该点的f值,及路径表;(3)重复上述步骤,直到取得终点;(4)根据路径表起点至终点的最短路径。

3、迪杰斯特拉算法复杂度迪杰斯特拉算法的时间复杂度和解空间复杂度都为O(n^2),其中n是节点数,即图中节点的个数。

(1)时间复杂度:迪杰斯特拉算法的时间复杂度为O(n*n),其中n表示节点个数,当图中节点越多时,迪杰斯特拉算法花费的时间就越多。

(2)空间复杂度:迪杰斯特拉算法的空间复杂度也是O(n*n),其中n表示节点个数,当图中节点越多时,迪杰斯特拉算法的空间复杂度也就越大。

4、迪杰斯特拉算法的优缺点(1)优点:迪杰斯特拉算法主要优点在于它简单明了、实现起来非常容易,运行效率也比较高。

(2)缺点:迪杰斯特拉算法的缺点在于在某些场景中,它的时间复杂度并不能满足要求,且对弧的代价分析比较粗糙,可操作性还有待提高。

如何优化算法以减少时间和空间复杂度

如何优化算法以减少时间和空间复杂度

如何优化算法以减少时间和空间复杂度在计算机科学中,算法的时间和空间复杂度是评估算法性能的重要指标。

时间复杂度衡量了算法在执行过程中所需的时间资源,而空间复杂度则衡量了算法在执行过程中所需的内存资源。

优化算法以减少时间和空间复杂度,可以提高算法的效率和性能。

本文将探讨一些优化算法的方法和技巧。

一、选择合适的数据结构选择合适的数据结构是优化算法的关键。

不同的数据结构适用于不同的问题和场景。

例如,对于需要频繁插入和删除操作的问题,链表可能比数组更加高效。

而对于需要随机访问的问题,数组可能是更好的选择。

因此,在设计算法时,要根据具体情况选择合适的数据结构,以减少时间和空间复杂度。

二、减少循环次数循环是算法中常见的结构,也是影响算法性能的重要因素之一。

循环次数越多,算法的时间复杂度就越高。

因此,减少循环次数可以有效地降低算法的时间复杂度。

在编写代码时,可以通过优化循环条件、提前终止循环等方式来减少循环次数,从而提高算法的效率。

三、使用适当的算法思想算法思想是解决问题的方法和策略,不同的算法思想适用于不同类型的问题。

例如,贪心算法适用于一些优化问题,动态规划适用于一些具有最优子结构性质的问题,分治算法适用于一些可以分解为子问题的问题等等。

选择合适的算法思想可以简化问题的解决过程,减少算法的时间和空间复杂度。

四、利用空间换时间有时,可以通过使用额外的内存空间来减少算法的时间复杂度。

例如,使用哈希表可以提高查找的效率,但同时也增加了空间复杂度。

在实际应用中,可以根据具体情况,权衡时间和空间复杂度的关系,选择合适的策略。

利用空间换时间的方法可以在一定程度上优化算法的性能。

五、剪枝和缓存剪枝和缓存是一种常见的优化算法的方法。

剪枝是指在搜索过程中,根据某些条件进行剪枝,减少不必要的计算。

例如,在搜索算法中,可以通过判断当前状态是否满足某些条件,来减少搜索的分支。

缓存是指将已经计算过的结果保存起来,避免重复计算。

通过剪枝和缓存的方法,可以减少算法的时间复杂度,提高算法的效率。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.时间复杂度
(1)时间频度一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。

但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。

并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。

一个算法中的语句执行次数称为语句频度或时间频度。

记为T(n)。

(2)时间复杂度在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。

但有时我们想知道它变化时呈现什么规律。

为此,我们引入时间复杂度概念。

一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。

记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

在各种不同算法中,若算法中语句执行次数为一个常数,则时间复杂度为O(1),另外,在时间频度不相同时,时间复杂度有可能相同,如 T(n)=n2+3n+4与T(n)=4n2+2n+1它们的频度不同,但时间复杂度相同,都为O(n2)。

按数量级递增排列,常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n), 线性对数阶O(nlog2n),平方阶O(n2),立方阶
O(n3),...,k次方阶O(nk),指数阶O(2n)。

随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。

2、空间复杂度与时间复杂度类似,空间复杂度是指算法在计算机内执行时所需存储空间的度量。

记作: S(n)=O(f(n)) 我们一般所讨论的是除正常占用内存开销外的辅助存储单元规模。

讨论方法与时间复杂度类似,不再赘述。

(3)渐进时间复杂度评价算法时间性能主要用算法时间复杂度的数量级(即算法的渐近时间复杂度)评价一个算法的时间性能。

【例3.7】有两个算法A1和A2求解同一问题,时间复杂度分别是T1(n)=100n2,T2(n)=5n3。

(1)当输入量n<20时,有T1(n)>T2(n),后者花费的时间较少。

(2)随着问题规模n的增大,两个算法的时间开销之比5n3/100n2=n/20亦随着增大。

即当问题规模较大时,算法A1比算法A2要有效地多。

它们的渐近时间复杂度O(n2)和O(n3)从宏观上评价了这两个算法在时间方面的质量。

在算法分析时,往往对算法的时间复杂度和渐近时间复杂度不予区分,而经常是将渐近时间复杂度T(n)=O(f(n))简称为时间复杂度,其中的f(n)一般是算法中频度最大的语句频度。

【例3.8】算法MatrixMultiply的时间复杂度一般为T(n)=O(n3),f(n)=n3是该算法中语
句(5)的频度。

下面再举例说明如何求算法的时间复杂度。

【例3.9】交换i和j的内容。

Temp=i; i=j; j=temp; 以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。

算法的时间复杂度为常数阶,记作 T(n)=O(1)。

如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。

此类算法的时间复杂度是O(1)。

【例3.10】变量计数之一。

(1) x=0;y=0;
(2) for(k-1;k<=n;k++)
(3) x++;
(4) for(i=1;i<=n;i++)
(5) for(j=1;j<=n;j++)
(6) y++;
一般情况下,对步进循环语句只需考虑循环体中语句的执行次数,忽略该语句中步长加1、终值判别、控制转移等成分。

因此,以上程序段中频度最大的语句是 (6),其频度为f(n)=n2,所以该程序段的时间复杂度为T(n)=O(n2)。

当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。

【例3.11】变量计数之二。

(1) x=1;
(2) for(i=1;i<=n;i++)
(3) for(j=1;j<=i;j++)
(4) for(k=1;k<=j;k++)
(5) x++;
该程序段中频度最大的语句是(5),内循环的执行次数虽然与问题规模n没有直接关系,但是却与外层循环的变量取值有关,而最外层循环的次数直接与n有关,因此可以从内层循环向外层分析语句(5)的执行次数:则该程序段的时间复杂度为T(n)=O(n3/6+低次项)=O(n3)。

(4)算法的时间复杂度不仅仅依赖于问题的规模,还与输入实例的初始状态有关。

【例3.12】在数值A[0..n-1]中查找给定值K的算法大致如下:
(1)i=n-1;
(2)while(i>=0&&(A[i]!=k))
(3) i--;
(4)return i;
此算法中的语句(3)的频度不仅与问题规模n有关,还与输入实例中A的各元素取值及K的取值有关: ①若A中没有与K相等的元素,则语句(3)的频度f(n)=n;②若A的最后一个元素等于K,则语句(3)的频度f(n)是常数0。

(5)最坏时间复杂度和平均时间复杂度最坏情况下的时间复杂度称最坏时间复杂度。

一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。

这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的上界,这就保证了算法的运行时间不会比任何更长。

【例3.19】查找算法
【例1·8】在最坏情况下的时间复杂度为T(n)=0(n),它表示对于任何输入实例,该算法的运行时间不可能大于0(n)。

平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,算法的期望运行时间。

常见的时间复杂度按数量级递增排列依次为:常数0(1)、对数阶0(log2n)、线形阶0(n)、线形对数阶0(nlog2n)、平方阶0(n2)立方阶0(n3)、…、k次方阶0(nk)、指数阶0(2n)。

显然,时间复杂度为指数阶0(2n)的算法效率极低,当n值稍大时就无法应用。

2、类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。

渐近空间复杂度也常常简称为空间复杂度。

空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。

一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。

算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。

存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。

算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地\"进行的,是节省存储的算法,如这一节介绍过的几个算法都是如此;有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着 n的增大而增大,当n较大时,将占用较多的存储单元,例如将在第九章介绍的快速排
序和归并排序算法就属于这种情况。

分析一个算法所占用的存储空间要从各方面综合考虑。

如对于递归算法来说,一般都比较简短,算法本身所占用的存储空间较少,但运行时需要一个附加堆栈,从而占用较多的临时工作单元;若写成非递归算法,一般可能比较长,算法本身占用的存储空间较多,但运行时将可能需要较少的存储单元。

一个算法的空间复杂度只考虑在运行过程中为局部变量分配的存储空间的大小,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。

若一个算法为递归算法,其空间复杂度为递归所使用的堆栈空间的大小,它等于一次调用所分配的临时存储空间的大小乘以被调用的次数(即为递归调用的次数加1,这个1表不开始进行的一次非递归调用)。

算法的空间复杂度一般也以数量级的形式给出。

如当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(10g2n);当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n).若形参为数组,则只需要为它分配一个存储由实参传送来的一个地址指针的空间,即一个机器字长空间;若形参为引用方式,则也只需要为其分配存储一个地址的空间,用它来存储对应实参变量的地址,以便由系统自动引用实参变量。

对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。

当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当=i自求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。

另外,算法的所有性能之间都存在着或多或少的相互影响。

因此,当设计一个算法(特别是大型算法)时,要综合考虑算法的各项性能,算法的使用频率,算法处理的数据量的大小,算法描述语言的特性,算法运行的机器系统环境等各方面因素,才能够设计出比较好的算法。

算法的时间复杂度和空间复杂度合称为算法的复杂度。

相关文档
最新文档