常用的排序算法的时间复杂度和空间复杂度
算法分类,时间复杂度,空间复杂度,优化算法

算法分类,时间复杂度,空间复杂度,优化算法算法 今天给⼤家带来⼀篇关于算法排序的分类,算法的时间复杂度,空间复杂度,还有怎么去优化算法的⽂章,喜欢的话,可以关注,有什么问题,可以评论区提问,可以与我私信,有什么好的意见,欢迎提出.前⾔: 算法的复杂度分为时间复杂度与空间复杂度,时间复杂度指执⾏算法需要需要的计算⼯作量,空间复杂度值执⾏算法需要的内存量,可能在运⾏⼀些⼩数据的时候,⼤家体会不到算法的时间与空间带来的体验. 优化算法就是将算法的时间优化到最快,将空间优化到最⼩,假如你写的mod能够将百度游览器的搜索时间提升0.5秒,那都是特别厉害的成绩.本章内容: 1,算法有哪些 2,时间复杂度,空间复杂度 3,优化算法 4,算法实例⼀,算法有哪些 常见的算法有冒泡排序,快排,归并,希尔,插⼊,⼆分法,选择排序,⼴度优先搜索,贪婪算法,这些都是新⼿⼊门必须要了解的,你可以不会,但是你必须要知道他是怎么做到的,原理是什么,今天就给⼤家讲⼀讲我们常⽤的冒泡排序,选择排序,这两个排序算法,1,冒泡排序(Bubble Sort), 为什么叫他冒泡排序呢? 因为他就像是从海底往海⾯升起的⽓泡⼀样,从⼩到⼤,将要排序的数从⼩到⼤排序,冒泡的原理: 他会⼀次⽐较两个数字,如果他们的顺序错误,就将其调换位置,如果排序正确的话,就⽐较下⼀个,然后重复的进⾏,直到⽐较完毕,这个算法的名字也是这样由来的,越⼤的数字,就会慢慢的'浮'到最顶端. 好了该上代码了,下⾯就是冒泡排序的代码,冒泡相对于其他的排序算法来说,⽐较的简单,⽐较好理解,运算起来也是⽐较迅速的,⽐较稳定,在⼯作中也会经常⽤到,推荐使⽤# 冒泡排序def bubble_sort(alist):n = len(alist)# 循环遍历,找到当前列表中最⼤的数值for i in range(n-1):# 遍历⽆序序列for j in range(n-1-i):# 判断当前节点是否⼤于后续节点,如果⼤于后续节点则对调if alist[j] > alist[j+1]:alist[j], alist[j+1] = alist[j+1], alist[j]if__name__ == '__main__':alist = [12,34,21,56,78,90,87,65,43,21]bubble_sort(alist)print(alist)# 最坏时间复杂度: O(n^2)# 最优时间复杂度: O(n)# # 算法稳定性:稳定2,选择排序(selection sort) 选择排序(selection sort)是⼀种简单直观的排序⽅法, 他的原理是在要排序的数列中找到最⼤或者最⼩的元素,放在列表的起始位置,然后从其他⾥找到第⼆⼤,然后第三⼤,依次排序,依次类,直到排完, 选择排序的优点是数据移动, 在排序中,每个元素交换时,⾄少有⼀个元素移动,因此N个元素进⾏排序,就会移动 1--N 次,在所有依靠移动元素来排序的算法中,选择排序是⽐较优秀的⼀种选择排序时间复杂度与稳定性:最优时间复杂度: O(n2)最坏时间复杂度:O(n2)算法稳定性 :不稳定(考虑每次升序选择最⼤的时候)# if alist[j] < alist[min_index]:# min_index = j## # 判断min_index索引是否相同,不相同,做数值交换# if i != min_index:# alist[i],alist[min_index] = alist[min_index],alist[i]### if __name__ == '__main__':# alist = [12,34,56,78,90,87,65,43,21]# # alist = [1,2,3,4,5,6,7,8,9]# select_sort(alist)# print(alist)# O(n^2)# 不稳定def select_sort(alist):"""选择排序"""n = len(alist)for i in range(n - 1):min_index = i # 最⼩值位置索引、下标for j in range(i+1, n):if alist[j] < alist[min_index]:min_index = j# 判断min_index ,如果和初始值不相同,作数值交换if min_index != i:alist[i], alist[min_index] = alist[min_index],alist[i]if__name__ == '__main__':alist = [8,10,15,30,25,90,66,2,999]select_sort(alist)print(alist)这是⼀些算法的时间复杂度与稳定性时间复杂度,空间复杂度 接下来就要来说说时间复杂度与空间复杂度: 时间复杂度就是假如你泡茶,从开始泡,到你喝完茶,⼀共⽤了多长时间,你中间要执⾏很多步骤,取茶叶,烧⽔,上厕所,接电话,这些都是要花时间的,在算法中,时间复杂度分为 O(1)最快 , O(nn)最慢,O(1) < O(logn) <O(n)<O(n2)<O(n3)<O(2n) <O(nn) ⼀般游览器的速度都在O(n),做我们这⼀⾏,要注意客户体验,如果你程序的运⾏特别慢,估计别⼈来⼀次,以后再也不会来了下⾯给⼤家找了张如何计算时间复杂度的图⽚: 空间复杂度(space complexity) ,执⾏时所需要占的储存空间,记做 s(n)=O(f(n)),其中n是为算法的⼤⼩, 空间复杂度绝对是效率的杀⼿,曾经看过⼀遍⽤插⼊算法的代码,来解释空间复杂度的,觉得特别厉害,我就⽐较low了,只能给⼤家简单的总结⼀下我遇到的空间复杂度了, ⼀般来说,算法的空间复杂度值得是辅助空间,⽐如:⼀组数字,时间复杂度O(n),⼆维数组a[n][m] :那么他的空间复杂度就是O(n*m) ,因为变量的内存是⾃动分配的,第⼀个的定义是循环⾥⾯的,所以是n*O(1) ,如果第⼆个循环在外边,那么就是1*O(1) ,这⾥也只是⼀个了解性的东西,如果你的⼯作中很少⽤到,那么没有必要深究,因为⽤的真的很少优化算法这边带来了代码,你们在复制下来了python上运⾏⼀下,看⼀下⽤的时间与不同, ⾃然就懂了,这是未优化的算法''已知有a,b,c三个数,都是0-1000之内的数,且: a+b+c=1000 ⽽且 a**2+b**2=c**2 ,求a,b,c⼀共有多少种组合'''# 在这⾥加⼀个时间模块,待会好计算出结果import time# 记录开头时间start_time=time.time()# 把a,b,c循环出来for a in range(1001):for b in range(1001):for c in range(100):# 判断他主公式第⼀次,并未优化if a+b+c==1000 and a**2 + b**2 == c**2 :# 打印print("a=" ,a)print("b=" ,b)print("c=" ,c)else:passstop_time = time.time()print('⼀共耗时: %f'%(stop_time-start_time))# ⼀共耗时 156.875001秒这是第⼀次优化import time# 记录开头时间start_time=time.time()# 把a,b,c循环出来for a in range(1001):# 这⾥改成1001-a之后,他就不⽤再循环b了for b in range(1001-a):for c in range(100):# 判断他主公式第⼆次,优化了b,if a+b+c==1000 and a**2 + b**2 == c**2 :print("a=" ,a)print("b=" ,b)print("c=" ,c)else:passstop_time = time.time()print('⼀共耗时: %f'%(stop_time-start_time))# ⼀共耗时 50.557070秒最后⼀次优化import time# 记录开头时间start_time=time.time()# 把a,b,c循环出来for a in range(1001):for b in range(1001-a):c=1000 - a - b# 判断他主公式第三次,优化了b和cif a+b+c==1000 and a**2 + b**2 == c**2 :print("a=" ,a)print("b=" ,b)print("c=" ,c)else:passstop_time = time.time()print('⼀共耗时: %f'%(stop_time-start_time))# ⼀共耗时 2.551449秒从156秒优化到l2秒, 基本运算总数 * 基本运算耗时 = 运算时间这之间的耗时和你的机器有着很⼤的关系今天是12⽉30⽇,明天就要跨年了,祝⼤家2019年事业有成,⼯资直线上升,早⽇脱单,。
算法与程序设计知识点

算法与程序设计知识点算法和程序设计是计算机科学中非常重要的概念和技术。
本文将介绍一些与算法和程序设计相关的知识点。
一、算法基础1. 什么是算法?算法是一系列解决问题的步骤和指令。
它描述了如何从输入数据中得出正确的输出结果。
2. 算法的特性良好的算法应具备以下特性:- 正确性:算法应能够产生正确的输出结果。
- 可读性:算法应易于理解和阅读。
- 高效性:算法应在合理时间内运行,并占用较少的计算资源。
3. 算法的复杂度算法的复杂度包括时间复杂度和空间复杂度。
时间复杂度描述了算法运行所需要的时间量,而空间复杂度则描述了算法所需的额外空间量。
二、数据结构1. 数组数组是一种线性数据结构,它由连续的内存空间组成,并存储相同类型的数据。
数组的访问、插入和删除操作能在O(1)时间内完成。
2. 链表链表是一种基础的数据结构,它由一系列节点组成,每个节点存储数据和指向下一个节点的引用。
链表的插入和删除操作能在O(1)时间内完成,但访问某个特定节点需要O(n)时间。
3. 栈栈是一种具有后进先出(LIFO)特性的数据结构。
栈的插入和删除操作都在栈顶进行,时间复杂度为O(1)。
4. 队列队列是一种具有先进先出(FIFO)特性的数据结构。
队列的插入操作在队尾进行,删除操作在队首进行,时间复杂度为O(1)。
三、常用算法1. 排序算法常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序和归并排序等。
这些排序算法在不同的数据规模下具有不同的时间复杂度。
2. 查找算法查找算法用于在给定的数据集合中寻找特定元素。
常见的查找算法有线性查找和二分查找,其中二分查找的时间复杂度为O(log n)。
3. 图算法图是一种非常重要的数据结构,图算法用于解决与图相关的问题,如最短路径问题、最小生成树问题和拓扑排序等。
四、编程语言1. C语言C语言是一种广泛使用的编程语言,它具有高效性和灵活性,尤其适合系统级编程。
2. Java语言Java语言是一种面向对象的编程语言,它具有跨平台性、安全性和可靠性,被广泛应用于企业级开发和移动开发。
算法调研报告

算法调研报告算法调研报告一、引言算法是计算机科学中的核心概念,它是一种有序的操作序列,用来解决特定问题或完成特定任务。
不同的算法在解决同一个问题时,可能会有不同的时间和空间复杂度,因此正确选择合适的算法对于程序的性能至关重要。
本报告将对几种常用的算法进行调研。
二、排序算法1. 冒泡排序冒泡排序是一种简单直观的排序算法,它重复地遍历要排序的数组,比较相邻元素的大小并交换,直到整个数组按照要求有序。
冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。
2. 快速排序快速排序是一种高效的排序算法,它采用分治的策略。
通过选择一个元素作为基准,将数组分成两部分,一部分小于基准,一部分大于基准,然后递归地对两部分进行排序。
快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。
三、查找算法1. 二分查找二分查找是一种在有序数组中查找特定元素的算法。
它通过比较中间元素和目标元素的大小关系,缩小查找范围,最终找到目标元素或确定目标元素不存在。
二分查找的时间复杂度为O(logn),空间复杂度为O(1)。
2. 哈希查找哈希查找是一种通过计算目标元素的哈希值,将其映射到数组中的位置进行查找的算法。
哈希查找的时间复杂度为O(1),但需要额外的空间来存储哈希表。
四、图算法1. 广度优先搜索广度优先搜索是一种用于图的遍历的算法。
它从图中的一个顶点开始,逐层遍历图中的顶点,直到所有顶点都被访问过。
广度优先搜索的时间复杂度为O(|V|+|E|),其中V为顶点数,E 为边数。
2. 最短路径算法最短路径算法用于寻找图中两个顶点之间的最短路径。
常见的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。
迪杰斯特拉算法适用于求解单源最短路径,时间复杂度为O(|V|^2)。
弗洛伊德算法适用于求解多源最短路径,时间复杂度为O(|V|^3)。
五、总结本报告对常用的排序算法、查找算法和图算法进行了调研,分析了它们的时间复杂度和空间复杂度。
常用排序算法分析比较

常用排序算法分析比较排序算法是计算机科学中的基本概念之一,它主要用于对一组元素进行排序,使得这些元素按照某种规则有序排列。
常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序、归并排序等等,这些算法都有自己的特点和适用场景,下面针对这些排序算法进行分析比较。
1.冒泡排序冒泡排序是一种简单的排序算法,它的主要思想是依次比较相邻的两个元素,如果它们的顺序不对就交换它们的位置,可以保证每次循环后最后一个元素是已经排序好的。
冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。
2.插入排序插入排序是一种稳定的排序算法,它的基本思想是将待排序的数据分为两个区间,已排序区间和未排序区间,在未排序区间内遍历,将每个元素插入到已排序区间的合适位置。
插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。
3.选择排序选择排序是一种比较简单的排序算法,它的主要思想是通过不断选择未排序区间内的最小值,然后和未排序区间的第一个元素交换位置,以此类推,直到排序完毕。
选择排序的时间复杂度为O(n^2),空间复杂度为O(1)。
4.快速排序快速排序是一种经典的排序算法,它的思想是采用分治的思想,将序列分为左右两个子序列,通过递归的方式对左右两个子序列进行快速排序,最后合并两个排好序的子序列。
快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。
5.归并排序归并排序是一种稳定的排序算法,它的基本思想是采用分治的思想,将序列分为左右两个子序列,通过递归的方式对左右两个子序列进行排序,最后将两个排好序的子序列合并成一个有序序列。
归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。
通过比较以上五种排序算法,可以发现每种算法都有自己的特点和适用场景,对于元素数量较少的情况下,可以选择冒泡排序、插入排序或选择排序,这些算法思路简单易懂,实现也比较容易;对于大规模数据排序,可以选择归并排序或快速排序,因为它们的时间复杂度比较优秀。
常用排序算法的时间复杂度和空间复杂度

常⽤排序算法的时间复杂度和空间复杂度以上快速排序和归并排序的空间复杂度不正确没有的参考图1,以图2为准(对,就是懒得重新画图了)排序法最差时间分析平均时间复杂度稳定度空间复杂度冒泡排序O(n2)O(n2)稳定O(1)快速排序O(n2)O(n*log2n)不稳定O(log2n)~O(n)选择排序O(n2)O(n2)稳定O(1)⼆叉树排O(n2)O(n*log2n)不稳定O(n)序插⼊排序O(n2)O(n2)稳定O(1)堆排序O(n*log2n)O(n*log2n)不稳定O(1)希尔排序O O不稳定O(1)1.插⼊排序由N-1趟排序组成,对于p=1到p=N-1趟,插⼊排序保证从位置0到位置p上的元素为已排序状态。
时间复杂度:O(N^2)代码void InsertionSort(ElementType A[],int N){int j,p;ElementType Tmp;for(p=1;p<N;p++){Tmp=A[j];//把A[j]保存下来,因为它要被插⼊到前⾯的某个位置去for(j=p;j>0&&A[j-1]>Tmp;j--)//⼤于A[j]的元素逐个后移{A[j]=A[j-1];}A[j]=Tmp;}}2.希尔排序希尔排序使⽤⼀个序列h1,h2,h3,ht,叫做增量排序。
在使⽤增量hk的⼀趟排序之后,对于每个i我们有A[i]<A[i+hk],所有相隔hk的元素被排序。
时间复杂度:O(N^(1+a)),其中0<a<1。
//代码不太好理解,使⽤了3层循环void ShellSort(ElementType A[],int N){int j,p,Increment;ElementType Tmp;for(Increment=N/2;Increment>0;Increment/=2){for(p=Increment;p<N;p++){Tmp=A[p];for(j=p;j>=Increment;j-=Increment){if(A[j]<A[j-Increment])A[j]=A[j-Increment];elsebreak;}A[j]=Tmp;}}}3. 堆排序思想:建⽴⼩顶堆,然后执⾏N次deleteMin操作。
算法分析与设计实验报告

算法分析与设计实验报告算法分析与设计实验报告一、引言算法是计算机科学的核心,它们是解决问题的有效工具。
算法分析与设计是计算机科学中的重要课题,通过对算法的分析与设计,我们可以优化计算机程序的效率,提高计算机系统的性能。
本实验报告旨在介绍算法分析与设计的基本概念和方法,并通过实验验证这些方法的有效性。
二、算法分析算法分析是评估算法性能的过程。
在实际应用中,我们常常需要比较不同算法的效率和资源消耗,以选择最适合的算法。
常用的算法分析方法包括时间复杂度和空间复杂度。
1. 时间复杂度时间复杂度衡量了算法执行所需的时间。
通常用大O表示法表示时间复杂度,表示算法的最坏情况下的运行时间。
常见的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)和O(n^2)等。
其中,O(1)表示常数时间复杂度,O(log n)表示对数时间复杂度,O(n)表示线性时间复杂度,O(n log n)表示线性对数时间复杂度,O(n^2)表示平方时间复杂度。
2. 空间复杂度空间复杂度衡量了算法执行所需的存储空间。
通常用大O表示法表示空间复杂度,表示算法所需的额外存储空间。
常见的空间复杂度有O(1)、O(n)和O(n^2)等。
其中,O(1)表示常数空间复杂度,O(n)表示线性空间复杂度,O(n^2)表示平方空间复杂度。
三、算法设计算法设计是构思和实现算法的过程。
好的算法设计能够提高算法的效率和可靠性。
常用的算法设计方法包括贪心算法、动态规划、分治法和回溯法等。
1. 贪心算法贪心算法是一种简单而高效的算法设计方法。
它通过每一步选择局部最优解,最终得到全局最优解。
贪心算法的时间复杂度通常较低,但不能保证得到最优解。
2. 动态规划动态规划是一种将问题分解为子问题并以自底向上的方式求解的算法设计方法。
它通过保存子问题的解,避免重复计算,提高算法的效率。
动态规划适用于具有重叠子问题和最优子结构的问题。
3. 分治法分治法是一种将问题分解为更小规模的子问题并以递归的方式求解的算法设计方法。
快速排序实验总结

快速排序实验总结快速排序是一种常用的排序算法,其基本思想是通过分治的方法将待排序的序列分成两部分,其中一部分的所有元素均小于另一部分的元素,然后对这两部分分别进行递归排序,直到整个序列有序。
下面是我在实验中对于快速排序算法的一些总结和思考。
一、算法步骤快速排序的基本步骤如下:1.选择一个基准元素(pivot),将序列分成两部分,一部分的所有元素均小于基准元素,另一部分的所有元素均大于等于基准元素。
2.对于小于基准元素的部分和大于等于基准元素的部分,分别递归地进行快速排序,直到两部分都有序。
3.合并两部分,得到完整的排序序列。
二、算法优缺点优点:1.快速排序的平均时间复杂度为O(nlogn),在排序大数据集时表现优秀。
2.快速排序是一种原地排序算法,不需要额外的空间,因此空间复杂度为O(logn)。
3.快速排序具有较好的可读性和可维护性,易于实现和理解。
缺点:1.快速排序在最坏情况下的时间复杂度为O(n^2),此时需要选择一个不好的基准元素,例如重复元素较多的序列。
2.快速排序在处理重复元素较多的序列时,会出现不平衡的分割,导致性能下降。
3.快速排序在递归过程中需要保存大量的递归栈,可能导致栈溢出问题。
三、算法实现细节在实现快速排序时,以下是一些需要注意的细节:1.选择基准元素的方法:通常采用随机选择基准元素的方法,可以避免最坏情况的出现。
另外,也可以选择第一个元素、最后一个元素、中间元素等作为基准元素。
2.分割方法:可以采用多种方法进行分割,例如通过双指针法、快速选择算法等。
其中双指针法是一种常用的方法,通过两个指针分别从序列的两端开始扫描,交换元素直到两个指针相遇。
3.递归深度的控制:为了避免递归过深导致栈溢出问题,可以设置一个递归深度的阈值,当递归深度超过该阈值时,转而使用迭代的方式进行排序。
4.优化技巧:在实现快速排序时,可以使用一些优化技巧来提高性能。
例如使用三数取中法来选择基准元素,可以减少最坏情况的出现概率;在递归过程中使用尾递归优化技术,可以减少递归栈的使用等。
计算机基础知识面试题及答案详解

计算机基础知识面试题及答案详解一、概述计算机基础知识是计算机科学与技术专业的重要基础,也是各大公司在招聘过程中常常考察的内容。
本文将详细解析一些常见的计算机基础知识面试题及其答案,帮助读者更好地准备面试。
二、数据结构与算法1. 什么是数据结构?数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
常见的数据结构包括数组、链表、栈、队列、树、图等。
2. 什么是算法?算法是指根据特定问题的求解需求,通过明确的步骤来描述解决问题的方法。
3. 请解释与算法相关的时间复杂度和空间复杂度的概念。
时间复杂度是衡量算法执行效率的指标,表示算法执行所需的时间资源。
空间复杂度是指算法执行所需的存储空间资源。
4. 请列举一些常见的排序算法,并比较它们的时间复杂度。
常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序、归并排序等。
其中,快速排序和归并排序的时间复杂度最优,为O(nlogn)。
5. 请解释什么是递归算法,并给出一个递归算法的示例。
递归算法是指在算法的描述中使用自身的定义或运算规则的算法。
例如,计算斐波那契数列可以使用递归算法,如下所示:```int fibonacci(int n) {if (n <= 1) {return n;} else {return fibonacci(n-1) + fibonacci(n-2);}}```三、操作系统1. 什么是操作系统?操作系统是一种控制和管理计算机硬件与软件资源的系统软件。
2. 请解释进程和线程的概念。
进程是指正在执行的一个程序或一段指令的实例。
线程是进程中的一个执行单元,每个进程至少包含一个线程,可以有多个线程。
3. 请解释死锁的概念及其产生的条件。
死锁是指两个或多个进程(线程)在执行过程中因争夺资源而造成的一种互相等待的现象。
死锁产生的条件包括互斥、占有并等待、不可抢占和循环等待。
4. 请解释虚拟内存的概念。
虚拟内存是一种内存管理技术,通过将磁盘上的一部分空间作为扩展内存来满足进程对内存空间的需求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
常用的排序算法的时间复杂度和空间复杂度
排序法最差时间分析平均时间复杂度稳定度空间复杂度
冒泡排序O(n2) O(n2) 稳定O(1)
快速排序O(n2) O(n*log2n) 不稳定O(log2n)~O(n) 选择排序O(n2) O(n2) 稳定O(1)
二叉树排序O(n2) O(n*log2n) 不一顶O(n) 插入排序O(n2) O(n2) 稳定O(1)
堆排序O(n*log2n) O(n*log2n) 不稳定O(1)
希尔排序O O 不稳定O(1)
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)渐进时间复杂度评价算法时间性能主要用算法时间复杂度的数量级(即算法的渐近时间复杂度)评价一个算法的时间性能。
2、类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。
渐近空间复杂度也常常简称为空间复杂度。
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。
一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。
算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。
存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。
算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地/"进行的,是节省存储的算法,如这一节介绍过
的几个算法都是如此;有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元,例如将在第九章介绍的快速排序和归并排序算法就属于这种情况。
如当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(10g2n);当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n).若形参为数组,则只需要为它分配一个存储由实参传送来的一个地址指针的空间,即一个机器字长空间;若形参为引用方式,则也只需要为其分配存储一个地址的空间,用它来存储对应实参变量的地址,以便由系统自动引用实参变量。