时间复杂度和空间复杂度的简单讲解

时间复杂度和空间复杂度的简单讲解一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量 把今年很流行 淡淡的基佬紫送给各位看官 原谅绿就算了 怕被打死 文章最后 举例使用二分查找和斐波那契的递归和迭代方法 分别说明时间和空间复杂度 时间复杂度 首先要说的是 时间复杂度的计算并不是计算程序具体运行的时间 而是算法执行语句的次数 当我们面前有多个算法时 我们可以通过计算时间复杂度 判断出哪一

一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量。

把今年很流行,淡淡的基佬紫送给各位看官,原谅绿就算了,怕被打死。

文章最后,举例使用二分查找和斐波那契的递归和迭代方法,分别说明时间和空间复杂度。

时间复杂度:
首先要说的是,时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。
当我们面前有多个算法时,我们可以通过计算时间复杂度,判断出哪一个算法在具体执行时花费时间最多和最少。




常见的时间复杂度有:
常数阶O(1),
对数阶O(log2 n),
线性阶O(n),
线性对数阶O(n log2 n),
平方阶O(n^2),
立方阶O(n^3)
k次方阶O(n^K),
指数阶O(2^n)。
随着n的不断增大,时间复杂度不断增大,算法花费时间越多。


















计算方法
①选取相对增长最高的项
②最高项系数是都化为1
③若是常数的话用O(1)表示
如f(n)=2*n3+2n+100则O(n)=n3。








通常我们计算时间复杂度都是计算最坏情况
时间复杂度的计算:
(1)如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。




 int x=1; while (x <10) { x++; } 

该算法执行次数是10,是一个常数,用时间复杂度表示是O(1)。

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

 for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { ; } } 

该算法for循环,最外层循环每执行一次,内层循环都要执行n次,执行次数是根据n所决定的,时间复杂度是O(n^2)。

(3)循环不仅与n有关,还与执行循环所满足的判断条件有关。

int i=0; while (i < n && arr[i]!=1) { i++; } 

在此循环,如果arr[i]不等于1的话,时间复杂度是O(n)。如果arr[i]等于1的话,则循环执行一次判断跳出,时间复杂度是O(1)。

空间复杂度
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
计算方法:
①忽略常数,用O(1)表示
②递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间
③对于单线程来说,递归有运行时堆栈,求的是递归最深的那一次压栈所耗费的空间的个数,因为递归最深的那一次所耗费的空间足以容纳它所有递归过程。










如:

int a; int b; int c; printf("%d %d %d \n",a,b,c); 

它的空间复杂度O(n)=O(1);

int fun(int n,) { int k=10; if(n==k) return n; else return fun(++n); } 

递归实现,调用fun函数,每次都创建1个变量k。调用n次,空间复杂度O(n*1)=O(n)。

#举例说明

1:实现二分查找算法的递归及非递归。(分析时间复杂度及空间复杂度)

迭代算法

#define _CRT_SECURE_NO_WARNINGS #include 
  
    #include 
   
     #include 
    
      int BinarySearch(int arr[], int len, int num) { assert(arr); int left = 0; int right = len - 1; int mid; while (left <= right) { mid = left + (right - left) / 2; if (num > arr[mid]) { left = mid + 1; } else if (num < arr[mid]) { right = mid - 1; } else { return mid; } } return -1; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9 }; int length = sizeof(arr) / sizeof(arr[0]); int aim = 9; int result; result = BinarySearch(arr, length, aim); if (result == -1) { printf("Can't find %d\n", aim); } else { printf("%d at %d postion\n", aim,result + 1); } return 0; } 
     
    
  

二分查找时,每次都在原有查找内容进行二分,所以时间复杂度为O(log2 n)
因为变量值创建一次,所以空间复杂度为O(1)

递归算法

int BinarySearchRecursion(int arr[5], int lef, int rig,int aim) { int mid = lef + (rig - lef) / 2; if (lef <= rig) { if (aim < arr[mid]) { rig = mid - 1; BinarySearchRecursion(arr, lef, rig, aim); } else if (arr[mid] < aim) { lef = mid + 1; BinarySearchRecursion(arr, lef, rig, aim); } else if (aim == arr[mid]) { return mid; } } else return -1; } int main() { int arr[] = { 1,2,3,5,6, }; int sz = sizeof(arr)/sizeof(arr[0]); int result; result = BinarySearchRecursion(arr, 0, sz - 1, 4); if (-1 == result) { printf("Can't find it.\n"); } else printf("Aim at %d location\n", result+1); } 

时间复杂度为O(log2 n)
每进行一次递归都会创建变量,所以空间复杂度为O(log2 n)

2:实现斐波那契数列的递归及非递归。(分析时间复杂度及空间复杂度)

迭代算法

int FeiBoNaCciInteration(int a,int b,int num) { int c; if (num <= 0) return -1; else if (num == 1) return a; else if (num == 2) return b; else { while (num - 2) { c = a + b; a = b; b = c; num--; } return c; } } int main() { int n; int result; printf("Input n\n"); scanf("%d", &n); result = FeiBoNaCciInteration(2, 3, n);//可自定义输入第一个数和第二个数 if (result == -1) { printf("Input Error!\n"); } else { printf("n is %d\n", result); } return 0; } 

时间复杂度O(n)
空间复杂度为O(1)

递归算法

int FeiBoNaCciRecursion(int num) { if (num < 0) return -1; if (num <= 2 && num > 0) return 1; else return FeiBoNaCciRecursion(num - 1) + FeiBoNaCciRecursion(num - 2); } int main() { int n; int result; printf("Input n\n"); scanf("%d", &n); result = FeiBoNaCciRecursion(n); if (result == -1) printf("Input Error!\n"); else printf("Result is %d\n", result); return 0; } 

时间复杂度为O(2^n)
空间复杂度为O(n)

欢迎在评论区留言提问,谢谢!

另外,如果觉得文章对你有用,下边点个打赏吧!

你们的支持,是我坚持的动力。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223975.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午12:59
下一篇 2026年3月17日 下午1:00


相关推荐

  • mpvue小程序轮播图绑定动态点击事件

    mpvue小程序轮播图绑定动态点击事件分享一个mpvue小程序轮播图绑定动态点击跳转页面,这个源码可以直接引用。

    2022年5月21日
    54
  • 深入理解Volatile关键字及其实现原理「建议收藏」

    深入理解Volatile关键字及其实现原理「建议收藏」volatile的用法volatile通常被比喻成"轻量级的synchronized",也是Java并发编程中比较重要的一个关键字。和synchronized不同,volatile是一个变量修饰符,只能用来修饰变量。无法修饰方法及代码块等。volatile的用法比较简单,只需要在声明一个可能被多线程同时访问的变量时,使用volatile修饰就可以了。如以下代码,是一个比较典型的使用双…

    2022年5月12日
    42
  • ggplot2数据分析与图形艺术_plot画多条曲线

    ggplot2数据分析与图形艺术_plot画多条曲线接着我们之前复现过的一篇NC文章(复现《naturecommunications》散点小提琴图+蜜蜂图),有一张关于差异蛋白的火山图,但是不同的是他的阈值设定不是我们普通的横向纵向,而是曲线阈值!image.png本来我以为这是一个个例,本篇文章作者博眼球的做法,但是检索了一下发现我付肤浅了,有很多文章,但是有一个特点,双曲线阈值应用在蛋白组差异基因的筛选上,这样的方式类似与“软阈值”吧,能够找到更显著的蛋白,值得在自己的研究中使用。image.png(Reference:ProteomicsofMe

    2026年4月13日
    5
  • css实现横向滚动条(css纵向滚动条)

    注意:(滚动条设置的width、height,分别是对应纵向滚动条宽度、横向滚动条高度,无法修改纵向滚动条高度、横向滚动条宽度数值只介绍Google浏览器滚动条样式,常用属性如下)::-webkit-scrollbar 滚动条整体样式 ::-webkit-scrollbar-button 一设置滚动条样式,滚动条两端的按钮图标就消失,但可以重新设置图片、新样式 ::-w…

    2022年4月10日
    227
  • Spark和Hadoop的区别和比较[通俗易懂]

    Spark和Hadoop的区别和比较[通俗易懂]目录一、两者的各方面比较二、Spark相对Hadoop的优越性三、三大分布式计算系统Spark,是分布式计算平台,是一个用scala语言编写的计算框架,基于内存的快速、通用、可扩展的大数据分析引擎Hadoop,是分布式管理、存储、计算的生态系统;包括HDFS(存储)、MapReduce(计算)、Yarn(资源调度)一、实现原理的比较Hadoop和Spark都是并…

    2025年7月6日
    4
  • 🚀保姆级教程!🚀谷歌Chrome DevTools MCP彻底颠覆AI浏览器自动化!让Cursor、Claude Codex CLI秒变浏览器控制神器,真正实现浏览器自动化,让AI为你打工!

    🚀保姆级教程!🚀谷歌Chrome DevTools MCP彻底颠覆AI浏览器自动化!让Cursor、Claude Codex CLI秒变浏览器控制神器,真正实现浏览器自动化,让AI为你打工!

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号