数据结构初阶:算法的时间复杂度和空间复杂度

什么是数据结构?

数据结构 (Data Structure) 是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的
数据元素的集合。

什么是算法?

算法 (Algorithm): 就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

算法效率

算法的复杂度

算法在编写成可执行程序后,运行时需要耗费时间资源和空间 ( 内存 ) 资源 。因此 衡量一个算法的好坏,一般 是从时间和空间两个维度来衡量的 ,即时间复杂度和空间复杂度。
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间 。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

时间复杂度

时间复杂度的概念

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

// 请计算一下Func1中++count语句总共执行了多少次?
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);
}

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要 大概执行次数,那么这 里我们使用大 O 的渐进表示法。(即估算,取影响最大的项)

O的渐进表示法

O 符号( Big O notation ):是用于描述函数渐进行为的数学符号。
推导大 O 阶方法:
1 用常数 1取代运行时间中的所有加法常数。
2 、在修改后的运行次数函数中,只保留最高阶项。(取决定性的项)
3 、如果最高阶项存在且不是 1 ,则去除与这个项目相乘的常数。得到的结果就是大 O 阶。
使用大 O 的渐进表示法以后, Func1 的时间复杂度为:O(N^2)
N = 10 F(N) = 100
N = 100 F(N) = 10000
N = 1000 F(N) = 1000000
通过上面我们会发现大 O 的渐进表示法 去掉了那些对结果影响不大的项 ,简洁明了的表示出了执行次数。
另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数 ( 上界 )
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数 ( 下界 )
例如:在一个长度为 N 数组中搜索一个数据 x
最好情况: 1 次找到
最坏情况: N 次找到
平均情况: N/2 次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)

常见时间复杂度计算举例

切记:时间复杂度是根据思想来计算的,而不是最后代码写完了才确定!!! 

二分查找 O(logN):(前提有序)

(以2为底的对数可省略 2不写,其他数不行)

 

空间复杂度

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

空间复杂度不是程序占用了多少 bytes 的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践复杂度类似,也使用 O 渐进表示法
注意: 函数运行时所需要的栈空间 ( 存储参数、局部变量、一些寄存器信息等 ) 在编译期间已经确定好了,因 此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。

 

具体看到空间复用的例子:

 

实例答案及分析:

1. 实例 1 使用了常数个额外空间,所以空间复杂度为 O(1)
2. 实例 2 动态开辟了 N 个空间,空间复杂度为 O(N)
3. 实例 3 递归调用了 N 次,开辟了 N 个栈帧,每个栈帧使用了常数个空间。空间复杂度为 O(N)

 

实际中更看重时间复杂度(效率),而不是空间复杂度(内存)

常见复杂度对比

一般算法常见的复杂度如下:

 常用的时间复杂度所耗费的时间从小到大的依次是:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) <O(n^3) < O(2^n) < O(n!) < O(n^n)

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

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

相关文章

Linux第85步_EXTI外部中断

1、在stm32mp157d-atk.dts文件中添加“led0”和“key0”节点 打开虚拟机上“VSCode”&#xff0c;点击“文件”&#xff0c;点击“打开文件夹”&#xff0c;点击“zgq”&#xff0c;点击“linux”&#xff0c;点击“atk-mp1”&#xff0c;点击“linux”&#xff0c;点击“my_l…

16.面向对象的软件测试技术

主要考点&#xff1a; 1、面向对象相关的基础概念&#xff1b;&#xff08;已经在软件工程的课程中讲过&#xff0c;要熟悉UML图&#xff0c;知道类和类之间的关系&#xff0c;这些知识也可能结合到下午题考察&#xff09; 2、面向对象的软件测试技术&#xff1b;&#xff08;大…

代码随想录 Day29 回溯算法 491.递增子序列 46.全排列 47.全排列 II

491.递增子序列 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {result.push_back(path);// 注意这里不要加return&#xff0c;要取树上…

Keil MDK 5.37 及之后版本 安装 AC5(ARMCC) 编译器详细步骤

由于 Keil 5.37 及之后版本不再默认安装 AC5(ARMCC) 编译器&#xff0c;这就会导致由 AC5 编译的工程无法正常编译&#xff0c;往往输出窗口会提示以下信息&#xff1a;*** Target ‘STM32xxxx‘ uses ARM-Compiler ‘Default Compiler Version 5‘ which is not available. —…

苹果应用上架流程解析

苹果上架要求是苹果公司对于提交应用程序到苹果商店上架的要求和规定。这些要求主要是为了保证用户体验、应用程序的质量和安全性。以下是苹果上架要求的详细介绍&#xff1a;1. 应用程序的内容和功能必须符合苹果公司的规 苹果上架要求是苹果公司对于提交应用程序到苹果商店上…

基于单片机控制的高速数据采集与处理系统研究

摘要针对现有单片机的数据处理速率较低不利于高速数据采集与处理的问题,文中研究并设计基于单片机控制的高速数据采集与处理系统。在数据采集方面,使用A/D 高速采样芯片实现高速数据采集。为满足高速数据处理与存储的需要,文中使用PC 终端的IDE 接口硬盘作为系统的存储装置。…

用Python标准GUI库Tkinter绘制分形图

用Python标准GUI库Tkinter绘制分形图 分形图是一种通过迭代规则生成自相似图案的艺术形式。 分形图包括曼德勃罗集、科赫曲线、谢尔宾斯基三角等代码等。 Tkinter是Python的标准GUI库&#xff0c;可以用于创建窗口、控件和其他图形界面元素。绘制分形图像&#xff0c;如曼德…

iPhone设备中如何分析和解决应用程序崩溃日志的问题

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

C语言—指针数组

从键盘任意输入一个整型表示的月份值&#xff0c;用指针数组编程输出该月份的英文表示&#xff0c;若输入的月份值不在1&#xff5e;12之间&#xff0c;则输出“Illegal month”。 **输入格式要求&#xff1a;"%d" 提示信息&#xff1a;"Input month number:&q…

从零开始 使用OMNET++结合VEINS,INET和SUMO的联合仿真

背景知识 当我们探索未来的交通系统和智能交通解决方案时&#xff0c;车辆到一切&#xff08;Vehicle-to-Everything, V2X&#xff09;通信技术显得尤为重要。V2X是指在车辆与车辆&#xff08;V2V&#xff09;、车辆与基础设施&#xff08;V2I&#xff09;、车辆与行人&#x…

0 决策树基础

目录 1 绪论 2 模型 3 决策树面试总结 1 绪论 决策树算法包括ID3、C4.5以及C5.0等&#xff0c;这些算法容易理解&#xff0c;适用各种数据&#xff0c;在解决各种问题时都有良好表现&#xff0c;尤其是以树模型为核心的各种集成算法&#xff0c;在各个行业和领域都有广泛的…

优化页面加载时间:改善用户体验的关键

✨✨ 祝屏幕前的您天天开心&#xff0c;每天都有好运相伴。我们一起加油&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一、为什么页面加载时间重要&#xff1f; 二、如何减少页面加载时间&#xff1f; …

分布式文件系统DFS

定义与概述 分布式文件系统&#xff08;Distributed File System, DFS&#xff09;是一种特殊的文件系统&#xff0c;其管理的物理存储资源并非直接连接在本地节点上&#xff0c;而是通过计算机网络与各个节点相连。这些节点可以简单地理解为一台台独立的计算机。DFS将分布在网…

干部任免管理系统开发(二) 数据库表的建设

前言: 字段照搬Lrmx文件内容 数据库表字段的设计基本上就是照搬Lrmx文件内容,没有什么过多的技术含量,也可以根据自己的需要对照Lrmx文件的格式自己去定义字段了。 软件的功能截图如下&#xff1a;核心就是能够任免审批表内容读取到数据库&#xff0c;生成lrmx和word格式方便做…

Nginx 部署静态文件

部署静态文件&#xff08;如HTML、CSS和JavaScript文件&#xff09;到一个Docker容器中&#xff0c;并使用Nginx作为web服务器是一个常见的做法。这种方式可以提高应用的性能和可靠性。下面是如何使用Docker和Nginx部署静态文件的一个基本步骤&#xff1a; 第一步&#xff1a;…

Netlink与RTNetlink的简单使用

Netlink与RTNetlink的简单使用 近期项目要求通过程序去配置下发网口路由&#xff0c;所以去了解了一下netlink机制。 一、netlink通信机制 netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。 目前&a…

java中的抽象类

抽象类是指包含了抽象方法的类。在java中&#xff0c;抽象方法指的是用abstract关键字进行修饰的方法&#xff0c;抽象方法与普通的方法的最大区别就是抽象方法没有方法体&#xff0c;也就是说抽象方法是没有具体的实现的。这也就意味着在抽象类的子类中调用抽象方法时&#xf…

蓝桥杯软件测试赛项--自动化测试

目录 Lanqiao_RJCS 1.自动化测试(Selenium+python) 分值:50 1.1. Webdriver初始化

Python脚本:pve平台自动获取名字、类型、节点、备注、状态。

此脚本可自动获取pve平台的信息。有兴趣或者有需要大家可以看看。 #anthor:bbxwg #explain:pve平台自动获取名字、类型、节点、备注、状态。 #Date:2024-3-29import os import subprocess import json import re from datetime import datetime#lkh:获取虚拟机IP地址函数 def …

SiteSucker Pro mac 5.3.2激活版 网站扒站神器

SiteSucker是一个Macintosh应用程序&#xff0c;可以从互联网自动下载网站。它通过将站点的网页、图像、PDF、样式表和其他文件异步复制到本地硬盘驱动器&#xff0c;复制站点的目录结构来实现此目的。只需输入一个URL&#xff08;统一资源定位器&#xff09;&#xff0c;按回车…