数据结构入门--时间 空间复杂度

news2024/9/22 17:34:08

数据结构入门 时间 空间复杂度解析

目录

一. 算法效率

二. 时间复杂度

2.1 时间复杂度的概念

2.2 大O的渐进表示法

2.3 题目练习

题目一

题目二

题目三

题目四

题目五

题目六

题目七

三. 空间复杂度

3.1 题目练习

题目一

题目二

题目三


一. 算法效率

算法效率分析分为两种:第一种是时间效率,第二种是空间效率。
时间效率被称为时间复杂度,而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小,所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。我们如今已经不需要再特别关注一个算法的空间复杂度。

总结经过这么久技术的发展 我们对于时间复杂度的要求高于空间复杂度的要求

二. 时间复杂度

2.1 时间复杂度的概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

2.2 大O的渐进表示法

我们直接上题目

// 请计算一下Func1基本操作执行了多少次?
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);
}

我们经过计算可以发现 这个函数需要运算的次数是 n的平方 加上 2*n 再加上10

当我们的n等于10的时候 它的次数是130

放我们的n是100的时候 它的次数是10210

当我们的n是1000的时候 它的次数是1002010

我们可以发现 它执行的次数实际上只跟n的平方有强相关性

这个时候我们只需要了解到这个程序的最高次项 我们就能估算出这个程序所需要运行的数量级

那么这里就能够引生出我们的大O的渐进表示法

推导大O阶方法:

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

使用大O的渐进表示法以后,Func1的时间复杂度为:

当n等于10的时候 它运行的次数就是100

当n等于100的时候 它运行的次数就是10000

当n等于1000的时候 它运行的次数就是1000000

此外 如果说随着我们输入的不同空间复杂度也有所改变的话 那么我们取最坏的空间复杂度作为我们的复杂度

2.3 题目练习

题目一

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

它计算的此时是2N+10

实际上的复杂度就是O(N)

题目二

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

它的计算的次数是 M+N次

实际的空间复杂度就是O(max(M,N))

题目三

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

这里实际上和N没有关系 它会计算100次

所以说它的次数是一个常数

常数的时间复杂度是O(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; 
 }
}

这里实际运行的次数是end的平方-n之后除以2

所以说 它的时间复杂度是O(N^2)

题目五

int BinarySearch(int* a, int n, int x) {
assert(a);
int begin = 0;
int end = n-1;
while (begin < end) {
 int mid = begin + ((end-begin)>>1);
 if (a[mid] < x)
 begin = mid+1;
 else if (a[mid] > x)
 end = mid;
 else
 return mid; }
return -1; }

它最好的运算情况是一次

运算最坏的情况是logN

所以说它的时间复杂度是logN

题目六

long long Factorial(size_t N) 
{
    return N < 2 ? N : Factorial(N-1)*N; 
}

实际上它的它的空间复杂度是O(N)

题目七

long long Fibonacci(size_t N) 
{
    return N < 2 ? N : Fibonacci(N-1)+Fibonacci(N-2);
}

实际上它的复杂度是 2的0次方加上2的一次放+…+2的N-1次方减去N

实际上它的它的空间复杂度是O(2^N)

实例答案及分析:

  1. 实例1基本操作执行了2N+10次,通过推导大O阶方法知道,时间复杂度为 O(N)
  2. 实例2基本操作执行了M+N次,有两个未知数M和N,时间复杂度为 O(N+M)
  3. 实例3基本操作执行了10次,通过推导大O阶方法,时间复杂度为 O(1)
  4. 实例4基本操作执行最好1次,最坏N次,时间复杂度一般看最坏,时间复杂度为 O(N)
  5. 实例5基本操作执行最好N次,最坏执行了(N*(N+1)/2次,通过推导大O阶方法+时间复杂度一般看最坏,时间复杂度为 O(N^2)
  6. 实例6基本操作执行最好1次,最坏O(logN)次,时间复杂度为 O(logN) ps:logN在算法分析中表示是底数为2,对数为N。有些地方会写成lgN。
  7. 实例7通过计算分析发现基本操作递归了N次,时间复杂度为O(N)。
  8. 实例8通过计算分析发现基本操作递归了2N次,时间复杂度为O(2N)。

三. 空间复杂度

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

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

实际上冒泡排序并没有占用额外的空间

所以说它使用的空间是常量级别的

所以说它的空间复杂度是O(1)

题目二

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

这里用来计算fib数 开辟了n+1个空间

实际上的空间复杂度是O(N)

题目三

long long Factorial(size_t N) {
 return N < 2 ? N : Factorial(N-1)*N; }

它实际上开辟了N到1数量的空间

所以说它的空间复杂度是O(N)

实际上这里我们要明确一点

时间是不能复用的
空间是可以复用的

 

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

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

相关文章

Vim常用命令汇总

目录1 普通模式2 插入模式3 可视模式4 命令行模式4 文件操作5 动作命令1 普通模式 命令操作符合命令作用等同命令.重复上次修改x删除光标下的字符dd删除整行>G从当前行到文档末尾处的缩进层级a在当前光标之后添加内容i在当前光标之前添加内容A在当前行的结尾添加内容$aI在当…

Docker之安装redis

下面记录一下在docker中安装redis过程 1.查看redis镜像 docker search redis2.拉去镜像到Linux //指定拉取redis版本 docker pull redis:6.0 //不指定版本默认拉取最新 docker pull redis3.查看镜像是否拉取成功 docker images4.启动redis //2f66aad5324为redis的image id do…

驾驭云安全:2023年云安全展望

由于其的良好的可扩展性和优质的事件处理效率&#xff0c;云技术已成为现代企业的必备的管理技术之一&#xff0c;目前他已经成为所有行业及企业的热门选择。然而&#xff0c;攻击面积的增加以及不针对云技术衍生出来的多类攻击方式&#xff0c;使许多企业更容易受到威胁和数据…

Docker学习总结

1、镜像操作 1.1 拉取、查看镜像 步骤一&#xff1a; 首先去镜像仓库搜索nginx镜像&#xff0c;比如[DockerHub]( Docker Hub Container Image Library | App Containerization ) : 步骤二&#xff1a; 根据查看到的镜像名称&#xff0c;拉取自己需要的镜像 通过命令&…

代码随想录 NO54 |单调栈_leetcode 503.下一个更大元素II 42. 接雨水

单调栈_leetcode 503.下一个更大元素II 42. 接雨水单调栈第二天&#xff0c;也是本轮刷题任务倒数第二天&#xff0c;加油&#xff01; 503.下一个更大元素II 这道题和739. 每日温度几乎如出一辙。在遍历的过程中模拟走了两遍nums。 class Solution:def nextGreaterElements(…

算法设计与分析——十大经典排序算法一(1--5)

目录 算法设计与分析——十大经典排序算法 第1关&#xff1a;冒泡排序 参考代码 第2关&#xff1a;选择排序 参考代码 第3关&#xff1a;插入排序 参考代码 第4关&#xff1a;希尔排序 参考代码 第5关&#xff1a;归并排序 参考代码 作者有言 一个不知名大学生&#x…

软考信息系统监理师备考建议

用好备考方法&#xff0c;两三个月就可以过的。信息系统监理师备考最好以教材和历年真题为主&#xff0c;教学视频模拟题为辅。考试介绍与复习建议&#xff1a;考试设置的科目包括&#xff1a;&#xff08;1&#xff09;信息系统工程监理基础知识&#xff0c;考试时间150分钟&a…

回顾1-idea创建Java项目

创建Java项目 创建项目和模块的区别 环境前置 IDEA开发工具JDK及配置环境变量 创建项目/工程 新建项目 选择Java模块 > SDK( 已配置的JDK ) > 下一步 直接下一步 填写项目信息 QQ游戏工程 里的 叫项目 所以 QQgame目录下 可以放 > 斗地主项目 / 美女来找茬等… …

Java调用C++方法(Linux下)

最近的项目中用到了java调用C的部分&#xff0c;记录一下&#xff0c;还是比较简单的。 所有需要的文件都放在同一个目录下。 java代码 public class NativeDemo {{System.load("/opt/java_c/src/NativeDemo.so");//这里必须用绝对路径}public native void SayHell…

Linux 进程:程序地址空间 与 虚拟内存

目录一、程序地址空间二、虚拟地址空间1.虚拟内存的原理2.使用虚拟内存的原因&#xff1f;3.如何实现虚拟空间&#xff1f;4.使用虚拟内存的好处本文主要介绍程序地址空间和虚拟地址空间的概念&#xff0c;理解了虚拟地址空间&#xff0c;才可以更好的理解物理内存和进程pcb之间…

scratch潜水 电子学会图形化编程scratch等级考试一级真题和答案解析2022年12月

目录 scratch潜水 一、题目要求 1、准备工作 2、功能实现 二、案例分析

# Redis 实战读书笔记(一)

Redis 实战读书笔记&#xff08;一&#xff09; 初始Redis ​ Redis是一个远程内存数据库&#xff0c;它不仅性能强劲而且还具有复制特性以及为解决问题而生的独一无二的数据模型。Redis提供了5中不同类型的数据库&#xff0c;初次之外通过复制持久化和客户端分片等特性用户可…

Android 项目必备(四十三)-->Android 开发者的 new 电脑

前言 作为 Android 开发者&#xff0c;当你新入职一家公司&#xff0c;拿到新发的电脑&#xff0c;你会对电脑干点啥&#xff1f; 安装开发环境&#xff1f;装软件&#xff1f;你是否还会铺天盖地到处找之前电脑备份的东西&#xff1f;又或者还想不起来有什么上一台电脑好用的…

一个9个月测试经验的人,居然在面试时跟我要18K,我都被他吓到了····

2月初我入职了深圳某家创业公司&#xff0c;刚入职还是很兴奋的&#xff0c;到公司一看我傻了&#xff0c;公司除了我一个测试&#xff0c;公司的开发人员就只有3个前端2个后端还有2个UI&#xff0c;在粗略了解公司的业务后才发现是一个从零开始的项目&#xff0c;目前啥都没有…

Mac iTerm2 rz sz

1、安装brew&#xff08;找了很多&#x1f517;&#xff0c;就这个博主的好用&#xff09; Mac如何安装brew&#xff1f;_行走的码农00的博客-CSDN博客_mac brew 2、安装lrzsz brew install lrzsz 检查是否安装成功 brew list 定位lrzsz的安装目录 brew list lrzsz 执…

【linux】:进程概念

文章目录 冯诺依曼体系结构一&#xff1a;操作系统二: 进程总结冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 冯诺依曼体系如下图&#xff1a; 那么输入设备有哪些呢&#xff1f…

时间复杂度和空间复杂度(1)

目录 1、算法效率 2、时间复杂度 1、定义 2、大O的渐进表示法 3、常见时间复杂度计算举例 3、空间复杂度 4、练习 例1、消失的数字 例2、旋转数组 1、算法效率 算法在编写成可执行程序后&#xff0c;运行时需要耗费计算机的时间资源和空间(内存)资源。因此衡量一个算法…

第八届蓝桥杯省赛——4承压计算(二维数组,嵌套循环)

题目&#xff1a;X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。每块金属原料的外形、尺寸完全一致&#xff0c;但重量不同。金属材料被严格地堆放成金字塔形。7 5 8 7 8 8 9 2 7 2 8 1 4 9 1 8 1 8 8 4 1 7 9 6 1 4 5 4 5 6 5 5 6 9 5 6 5 5 4 7 9 3 5 5 1 7 5 7 9 7 4…

Unity 渲染流程管线

渲染流程图可以把它理解为一个流程&#xff0c;就是我们告诉GPU一堆数据&#xff0c;最后得出来一副二维图像&#xff0c;而这些数据就包括了”视点、三维物体、光源、照明模型、纹理”等元素。参考如下图(来自视频)CPU应用阶段剔除视锥剔除由Unity依据Camera直接完成&#xff…

PowerShell Install Tomcat

Tomcat 前言 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首选。对于一个初学者来说&#xff0c;可以这样认为&#xff0c;当…