当前位置: 首页 > news >正文

算法复杂度解析:时间与空间的衡量

一、什么是算法复杂度

        算法复杂度是用来衡量一个算法的好坏的,算法复杂度可以分为时间复杂度和空间复杂度。

        时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额为空间。

二、时间复杂度

        简单来说,时间复杂度就是基本语句的执行次数。

        我们通常使用O()来表示一个算法的复杂度,O()是用来描述函数渐进应为的数学符号。

大O的使用有以下几点规则:

        1. 只保留最高阶项,去掉低阶项。--> 当N不断变大时,低阶项的影响越来越小,N无穷大时,可以忽略不计

        2. 去除常数系数。 --> 当N不断变大时,系数对结果影响越来越小,N无穷大时,可以忽略不计

        3. 如果只有常数项,用常数1取代所有加法常数。

1. 例1

void Func1(int N) 
{ int count = 0; for (int k = 0; k < 2 * N ; ++ k) { ++count; } int M = 10; while (M--) { ++count; } printf("%d\n", count); 
}

        观察上面代码,可以发现该程序的操作次数为 2N+10 ,根据大O的使用规则可以得出,该算法的时间复杂度为 O(N)

2.例2

void Func2(int N) 
{ int count = 0; for (int k = 0; k < 100; ++ k) { ++count; } printf("%d\n", count); 
}

        观察上方代码,可以发现该程序的操作次数为 100 ,根据大O的使用规则可以得出,该算法的时间复杂度为 O(1)

3.例3

const char * strchr ( const char * str, int character){const char* p_begin = s;while (*p_begin != character){if (*p_begin == '\0')return NULL;p_begin++;}return p_begin;}

        strchr函数用于在字符串中查找指定字符首次出现的位置。观察上方代码可以发现当要查找的字符在字符串不同位置时,程序的操作次数时不一样的,所以strchr的时间复杂度存在 最好、最坏、平均情况。⼤O的渐进表⽰法在实际中⼀般情况关注的是算法的上界,也就是最坏运⾏情况。

strchr执行的基本操作次数:
        1. 最好情况:如果要查找的字符在字符串第一个位置,则为 1

        2. 最坏情况:如果要查中的字符在字符串最后一个位置,则为 N

        3. 平均情况:如果要查找的字符在字符串中间位置,则为 N/2

所以,strchr的时间复杂度分为:

        1.最好情况:O(1)

        2.最坏情况:O(N)

        3.平均情况:O(N)

4.例4

void func3(int n){int cnt = 1;while (cnt < n){cnt *= 2;}}

        观察上面代码,可以发现 2^x=n(x为操作次数)。该程序的操作次数为 log n ,根据大O的使用规则可以得出,该算法的时间复杂度为 O(log n)

        ⼀般情况下不管底数是多少都可以省略不写,即可以表⽰为 log n

5.例5

long long Fac(size_t N) 
{ if(0 == N) return 1; return Fac(N-1)*N; 
}

        调⽤⼀次Fac函数的时间复杂度为 O(1) 。⽽在Fac函数中,存在 n 次递归调⽤Fac函数 因此阶乘递归的时间复杂度为: O(n)。

三、空间复杂度

        函数运⾏时所需要的栈空间(存储参数、局部变量、⼀些寄存器信息等)在编译期间已经确定好 了,因此空间复杂度主要通过函数在运⾏时候显式申请的额外空间来确定。

1.例1

void BubbleSort(int* a, int n) 
{ assert(a); for (size_t end = n; end > 0; --end) { int exchange = 0; for (size_t i = 1; i < end; ++i) { if (a[i-1] > a[i]) { Swap(&a[i-1], &a[i]); exchange = 1; } } if (exchange == 0) break; } 
}

        BubbleSort额外申请的空间有 exchange 等有限个局部变量,使⽤了常数个额外空间因此空间复杂度为 O(1)

2.例2

long long Fac(size_t N) 
{ if(N == 0) return 1; return Fac(N-1)*N; 
}

        Fac递归调⽤了N次,额外开辟了N个函数栈帧, 每个栈帧使⽤了常数个空间。因此空间复杂度为: O(N)。

四、常见复杂度

复杂度 常见场景
O(1)操作次数与输入规模无关,固定次数
O(log n)每次操作将问题规模缩小一半(底数通常为 2)
O(n log n)线性时间与对数时间的乘积,常见于分治思想算法
O(n)操作次数与输入规模成正比
O(n^2)操作次数与输入规模的平方成正比
O(2^n)操作次数随输入规模呈指数级增长(基数为 2)
O(n!)操作次数随输入规模呈阶乘级增长,效率极低
http://www.dtcms.com/a/585130.html

相关文章:

  • 开源鸿蒙SIG-Qt技术沙龙成都站成功举办,产品方案展示
  • 2025年渗透测试面试题总结-235(题目+回答)
  • C语言进阶:深入理解函数
  • 计算机图形学·11 变换(Transformations)
  • Rust编程学习 - 如何利用代数类型系统做错误处理的另外一大好处是可组合性(composability)
  • LocalAI:一个免费开源的AI替代方案,让创意更自由!
  • 深入理解Ext2:Linux文件系统的基石与它的设计哲学
  • 泉州网站的建设html网页制作我的家乡
  • PHP 魔术常量
  • 【iOS】音频与视频播放
  • php通过身份证号码计算年龄
  • 基于PHP+Vue+小程序快递比价寄件系统
  • Next.js、NestJS、Nuxt.js 是 **Node.js 生态中针对不同场景的框架**
  • 牛客周赛 Round 114 Java题解
  • PostgreSQL 中数据库、用户、对象关系、表、连接及管理概述
  • 樟树市城乡规划建设局网站爱站攻略
  • Gitblit 迁移指南
  • Git分支管理核心:git fetch与git checkout创建分支完全指南
  • LRU 缓存的设计与实现
  • Linux -- 线程互斥
  • 2.2 Transformer 架构详解:从理论到实践
  • 《Docker+New Relic+Jenkins:开发全链路的工具赋能指南》
  • 2025最新修复的豪门足球风云-修复验证问题-修复注册问题实现地注册-架设教程【豪门足球本地验证】
  • 【Linux笔记】网络部分——数据链路层mac-arp
  • 深圳网站设计公司专业吗外国网站分享代码
  • VB.Net 常用函数
  • 成都哪家做网站wordpress 主题课堂
  • 智慧随访管理系统源码,基于Java+Spring Boot+Vue的随访系统源码,支持二次开发,支持患者信息管理、多类型随访、三级回访机制、问卷模板
  • MQL5 自学路线图:从入门到实战
  • 告别 mysqldump 痛点!用 mydumper 实现 MySQL 高效备份与恢复