【数据结构初阶】复杂度

news2024/11/15 7:28:13

目录

一、时间复杂度

        1、时间复杂度的概念

        2、大O的渐进表示法

        3、常见的时间复杂度计算举例

二、空间复杂度

        1、空间复杂度的概念

        2、常见的空间复杂度计算举例

三、常见复杂度对比


正文开始——

前言

一个算法,并非越简洁越好,那该如何衡量一个算法的好坏呢?看其复杂度。复杂度又分为时间复杂度空间复杂度

一、时间复杂度 

1.  时间复杂度的概念 

在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行程序所消耗的时间,从理论上说,是不能算出来的,只有上机测试才能得知,于是我们有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比,算法中的基本操作的执行次数,为算法的时间复杂度。

 void Func1(int N)
{
    int count = 0;
    for (int i = 0; i < N ; ++ i)
   {
     for (int j = 0; j < N ; ++ j)
    {
         ++count;
    }
    for (int k = 0; k < 2 * N ; ++ k)
    {
     ++count;
    }


    int M = 10;
    while (M--)
    {
     ++count;
    }
    
    printf("%d\n",count);
}

Func1执行的基本次数:N^2+2*N+10

实际计算时间复杂度,我们不一定要精确计算执行次数,只需要计算大概的执行次数,那么这里我们使用大O的渐进表示法。

2.  大O的渐进表示法 

大O符号:是用于描述函数渐进行为的数学符号。

推导大O阶方法:

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留最高阶项。
  3. 如果最高阶项存在且不为1,则去除与这个项相乘的常数。得到的结果就是大O阶。

so Func1的时间复杂度为:O(N^2)。通过上面我们发现大O的渐进法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。

另外有些算法的时间复杂度存在最好、平均和最坏情况:

最坏情况:任意输入规模的最大运行次数(上界)

平均情况:任意输入规模的期望运行次数

最好情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x

最坏情况:N次找到

平均情况:N/2次找到

最好情况:1次找到

在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据x的时间复杂度为O(N)。

3.  常见的时间复杂度计算举例 

实例1:

//计算Func2的时间复杂度

void Func2(int N)
{
    int count=0;
    for(int k=0;k<2*N;k++)
    {
        ++count;
    }

    int M=10;
    while(M--)
    {
        ++count;
    }

    printf("%d\n",count);
}

【解析】Func2执行的基本次数:N*2+10 ,所以其时间复杂度为:O(N)。

实例2:

//计算Func3的时间复杂度

void Func3(int N,int M)
{
    int count=0;
    for(int k=0;k<M;++k)
    {
        ++count;
    }

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

【解析】Func3执行的基本次数:M+ N,有两个未知数M,N,时间复杂度:O(M+N)。

实例3:

//计算Func4的时间复杂度

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

【解析】Func4执行的基本次数:100,对于常数一律用O(1)。

实例4:

//计算strchr的时间复杂度

const char* strchr (const char* str,int character);

【解析】基本操作最好情况执行1次,最坏N次,时间复杂度一般看最坏,时间复杂度为O(N)。

实例5:

//计算BubbleSort的时间复杂度

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;
    }
}

【解析】基本操作最好情况执行N次,最坏执行(N*(N+1))/2次,所以时间复杂度为O(N^2).

实例6:

int BinarySearch(int* a, int n, int x)
{
     assert(a); 

     int begin = 0;
     int end = n-1;
     // [begin, end]:begin和end是左闭右闭区间,因此有=号
     while (begin <= end)
    {
         int mid = begin + ((end-begin)>>1);
         if (a[mid] < x)
             begin = mid+1;
         else if (a[mid] > x)
             end = mid-1;
         else
             return mid;
    }
     return -1;
}

【解析】基本操作最好执行1次,最坏O(logN)次,时间复杂度为O(logN)。ps:logN在算法分析中表示底数为2,对数为N。

实例7:

// 计算阶乘递归Fac的时间复杂度
long long Fac(size_t N)
{
    if(0 == N)
         return 1;
 
    return Fac(N-1)*N;
}

【解析】递归了N次,时间复杂度为O(N)。

实例8:

// 计算斐波那契递归Fib的时间复杂度
long long Fib(size_t N)
{
     if(N < 3)
     return 1;
 
     return Fib(N-1) + Fib(N-2)
}

【解析】时间复杂度为O(2^N)。

二、空间复杂度 

1.  空间复杂度的概念 

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度

空间复杂度不是程序占用了多少bytes的空间,因为这个也没有太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则与时间复杂度相似,也是用大O渐进表示法。

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

2.  常见空间复杂度计算举例 

实例1:

// 计算BubbleSort的空间复杂度?
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;
   }
}

【解析】 在函数运行过程中申请常数个额外空间,所以空间复杂度为O(1)。

实例2:

// 计算Fibonacci的空间复杂度
// 返回斐波那契数列的前n项
long long* Fibonacci(size_t n)
{
     if(n==0)
         return NULL;
 
     long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));
     fibArray[0] = 0;
     fibArray[1] = 1;
     for (int i = 2; i <= n ; ++i)
    {
        fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
    }
 
    return fibArray;
}

【解析】 动态开辟了N个空间,所以空间复杂度为O(N)。

实例3:

// 计算阶乘递归Fac的空间复杂度
long long Fac(size_t N)
{
     if(N == 0)
     return 1;
 
     return Fac(N-1)*N;
}

【解析】递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)。

三、常见复杂度对比 


完——

——————————————————   绿色   ——————————————————

绿色_陈雪凝_高音质在线试听_绿色歌词|歌曲下载_酷狗音乐酷狗音乐为您提供由陈雪凝演唱的高清音质无损绿色mp3在线听,听绿色,只来酷狗音乐!icon-default.png?t=N7T8https://t4.kugou.com/song.html?id=7dQq7a4CPV2

 你是否也期待来一场说走就走的旅行——

 期待我们下一次的相遇——

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mamba-yolo|结合Mamba注意力机制的视觉检测

一、本文介绍 PDF地址&#xff1a;https://arxiv.org/pdf/2405.16605v1 代码地址&#xff1a;GitHub - LeapLabTHU/MLLA: Official repository of MLLA Demystify Mamba in Vision: A Linear AttentionPerspective一文中引入Baseline Mamba&#xff0c;指明Mamba在处理各种高…

零基础入门:创建一个简单的Python爬虫管理系统

摘要&#xff1a; 本文将手把手教你&#xff0c;从零开始构建一个简易的Python爬虫管理系统&#xff0c;无需编程基础&#xff0c;轻松掌握数据抓取技巧。通过实战演练&#xff0c;你将学会设置项目、编写基本爬虫代码、管理爬取任务与数据&#xff0c;为个人研究或企业需求奠…

回溯题目的套路总结

前言 昨天写完了LeeCode的7&#xff0c;8道回溯算法的题目&#xff0c;写一下总结&#xff0c;这类题目的共同特点就是暴力搜索问题&#xff0c;排列组合或者递归&#xff0c;枚举出所有可能的答案&#xff0c;思路很简单&#xff0c;实现起来的套路也很通用&#xff0c;一…

poi库简单使用(java如何实现动态替换模板Word内容)

目录 Blue留言&#xff1a; Blue的推荐&#xff1a; 什么是poi库&#xff1f; 实现动态替换 第一步&#xff1a;依赖 第二步&#xff1a;实现word模板中替换文字 模板word&#xff1a; 通过以下代码&#xff1a;&#xff08;自己建一个类&#xff0c;随意取名&#xf…

SpringBoot框架学习笔记(五):静态资源访问、Rest风格请求处理、配置视图解析器、接收参数的相关注解详解

1 WEB开发-静态资源访问 1.1 基本介绍 &#xff08;1&#xff09;只要静态资源放在类路径的以下目录&#xff1a;/static、/public、/resources、/META-INF/resources 可以被直接访问。maven项目的类路径即为main/resources目录--对应SpringBoot源码为WebProperties.java类 …

nginx如何开启优先访问压缩文件

nginx输出gzip有很多条件&#xff1a; 开启了gzip&#xff1a;gzip on;gzip_types定义了content-type&#xff0c;需要注意的是text/html是强制性的&#xff0c;不需要也不能再添加这个响应输出的content-type在gzip_types里输出的content-length大于等于nginx配置的gzip_min_…

【TypeScript 一点点教程】

文章目录 一、开发环境搭建二、基本类型2.1 类型声明2.2 基本类型 三、编译3.1 tsc命令3.2 tsconfig.json3.2.1 基本配置项includeexcludeextendsfiles 3.2.2 compilerOptions编译器的配置项 四、面向对象4.1 类4.2 继承4.3 抽象类4.4 接口 一、开发环境搭建 下载Node.js《Nod…

操作系统——进程与线程(死锁)

1&#xff09;为什么会产生死锁&#xff1f;产生死锁有什么条件&#xff1f; 2&#xff09;有什么办法解决死锁&#xff1f; 一、死锁 死锁:多个程序因竞争资源而造成的一种僵局&#xff08;互相等待对方手里的资源&#xff09;&#xff0c;使得各个进程都被阻塞&#xff0c;…

02.C++入门基础(下)

1.函数重载 C支持在同一作用域中出现同名函数&#xff0c;但是要求这些同名函数的形参不同&#xff0c;可以是参数个数不同或者类型不同。这样C函数调用就表现出了多态行为&#xff0c;使用更灵活。C语言是不支持同一作用域中出现同名函数的。 1、参数类型不同 2、参数个数不同…

volatile,最轻量的同步机制

目录 一、volatile 二、如何使用&#xff1f; 三、volatile关键字能代替synchronized关键字吗&#xff1f; 四、总结&#xff1a; 还是老样子&#xff0c;先来看一段代码&#xff1a; 我们先由我们自己的常规思路分析一下代码&#xff1a;子线程中&#xff0c;一直循环&…

DocRED数据集

DocRED数据集文件夹包含多个JSON文件&#xff0c;每个文件都有不同的用途。以下是这些文件的用途解释以及哪个文件是训练集&#xff1a; 文件解释 dev.json&#xff1a;包含开发集&#xff08;验证集&#xff09;的数据&#xff0c;通常用于模型调优和选择超参数。 label_map…

java面向对象进阶进阶篇--《包和final》

一、前言 今天还是面向对象相关知识点的分享&#xff0c;包是写小型项目时不可或缺的存在&#xff0c;final关键字用的地方不算太多。idea会提示我们导包&#xff0c;有时会自动导包&#xff0c;确实十分方便。但是我们也不能不会自己去导包。 面向对象篇不出意外的话本周就要…

【线性代数】矩阵变换

一些特殊的矩阵 一&#xff0c;对角矩阵 1&#xff0c;什么是对角矩阵 表示将矩阵进行伸缩&#xff08;反射&#xff09;变换&#xff0c;仅沿坐标轴方向伸缩&#xff08;反射&#xff09;变换。 2&#xff0c;对角矩阵可分解为多个F1矩阵&#xff0c;如下&#xff1a; 二&a…

python打包exe文件-实现记录

1、使用pyinstaller库 安装库&#xff1a; pip install pyinstaller打包命令标注主入库程序&#xff1a; pyinstaller -F.\程序入口文件.py 出现了一个问题就是我在打包运行之后会出现有一些插件没有被打包。 解决问题&#xff1a; 通过添加--hidden-importcomtypes.strea…

“微软蓝屏”事件引发的深度思考:网络安全与系统稳定性的挑战与应对

“微软蓝屏”事件暴露了网络安全哪些问题&#xff1f; 近日&#xff0c;一次由微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;不仅成为科技领域的热点新闻&#xff0c;更是一次对全球IT基础设施韧性与安全性的深刻检验。这次事件&#xff0c;源于美国电脑安全…

【Vue3】工程创建及目录说明

【Vue3】工程创建及目录说明 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日…

全网最全最详细的C++23 标准详解:核心语言改进与新特性

1. 简介 C23 是由 C 标准委员会最新发布的标准&#xff0c;旨在进一步提升 C 语言的功能和开发效率。作为一项重要的编程语言标准更新&#xff0c;C23 引入了多个关键的新特性和改进&#xff0c;使开发者能够编写更高效、简洁和安全的代码。 与 C20 相比&#xff0c;C23 的变…

3112.力扣每日一题7/18 Java 迪杰斯特拉(Dijkstra)算法

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 迪杰斯特拉&#xff08;Dijkstra&#xff09;算法 解题思路 解题过…

C++学习指南(三)——模板

欢迎来到繁星的CSDN。本期内容主要包括模板template。 目录 一、什么是模板&#xff1f; 二、函数模板 模板的定义方式 模板的实例化&#xff08;确定参数的类型&#xff09; 隐式实例化 显式实例化 实例化顺序 三、类模板和模板类 类模板的实例化 一、什么是模板&#xff1…

智慧职校就业管理:开启校园招聘会新模式

在智慧职校的就业管理系统中&#xff0c;校园招聘会的出现&#xff0c;为学生们提供了一个展示自我、探寻职业道路的舞台&#xff0c;同时也为企业搭建了一座直面未来之星的桥梁。这一功能&#xff0c;凭借其独特的优势与前沿的技术&#xff0c;正在重新定义校园与职场之间的过…