【数据结构与算法——TypeScript】算法的复杂度分析、 数组和链表的对比

【数据结构与算法——TypeScript】

算法的复杂度分析

什么是算法复杂度(现实案例)?

❤️‍🔥 前面已经解释了什么是算法? 其实就是解决问题的一系列步骤操作、逻辑。
对于同一个问题,我们往往有很多种解决思路和方法,也就是可以采用不同的算法。

  • 举个例子(现实例子):在一个庞大的图书馆中,我们需要找一本书

    • 在图书已经按照某种方式摆好的情况下(数据结构是固定的)
  • 方式一:顺序查找

    • 一本一本找,直到找到想要的书;
  • 方式二:先分类找,分类中找这本书

    • 先找到分类,在分类中再顺序或某种方式查找
  • 方式三:找到检索电脑,查找书的位置,直到找到

    • 图书馆通常有自己的图书管理系统
    • 利用图书管理系统先找到书的位置,再直接过去找到

什么是算法复杂度(程序案例)?

🖥 在具体一个程序中的案例:让我们用两种不同算法查找数组中(数组有序)给定元素的复杂度

  • ✅ 方式一:顺序查找
    • 这种算法 从头到尾遍历整个数组,依次比较每个元素和给定元素的值
    • 如果 找到相等的元素,则返回下标;如果 遍历完整个数组都没找到,则返回 -1

复杂度-顺序查找

  /**- 顺序查找- @param array 查找的数组- @param 查找的元素- @returns 查找到的索引,未找到返回-1*/function sequentSearch(array: number[], num: number) {for (let i = 0; i < array.length; i++) {const element = array[i];if (element === num) return i;}return -1;}const index = sequentSearch([1, 3, 5, 10, 100, 222, 333, 334, 555, 556], 222);console.log(index);
  • ✅ 方式二:二分查找

    • 这种算法假设数组是有序的,每次 选择数组中间的元素与给定元素进行比较
    • 如果 相等,则返回下标;如果 给定元素比中间元素小,则在数组的左半部分继续查找
    • 如果 给定元素比中间大,则在数组的右半部分继续查找
    • 这样 每次查找都会将查找范围减半,直到找到想等的元素或者查找范围为空

    在这里插入图片描述

    function binarySearch(array: number[], num: number) {
    // 1. 定义左右索引
    let left = 0;
    let right = array.length - 1;// 2.开始查找
    while (left <= right) {let mid = Math.floor((left + right) / 2);const midNum = array[mid];if (midNum === num) {return mid;} else if (midNum < num) {left = mid + 1;} else {right = mid - 1;}
    }
    return -1;
    }
    const index = binarySearch([1, 3, 5, 10, 100, 222, 333, 334, 555, 556], 222);
    console.log(index);
    export {};
    

测试顺序查找和二分查找的代码

  • 使用🔧工具: npm install hy-algokit
import sequentSearch from './01_查找算法-顺序查找';
import binarySearch from './02_查找算法-二分查找';
import { testOrderSearchEfficiency } from 'hy-algokit';
testOrderSearchEfficiency(sequentSearch);
testOrderSearchEfficiency(binarySearch);

在这里插入图片描述

  • ❤️‍🔥 顺序查找算法的时间复杂度是 O(n)

  • ❤️‍🔥 二分查找算法的时间复杂度是 O(log n)

大O表示法(Big O notation)

  • 大O表示法(Big O notation)英文翻译为大O符号,中文通常翻译为大O表示法(标记法)。
  • 大O符号在分析 算法效率的时候非常有用
    • 🌰 举例:解决 **一个规模为n的问题所花费的时间(或需要步骤的数目)可以表示为:
      • T(n)= 4n⌃2^ - 2n + 2**
      • n 增大 时, n^2^ 项开始 占据主导地位,其他各项可以被忽略
    • 🌰 : 当 n = 500
      • 4n2 项是 2n 项的 1000倍大,因此在大多数场合下, 省略后者对表达式的值的影响将是乐意忽略不计的

      • 进一步,如果我们与任一其他级的表达式比较, n2的系数也是无关紧要的的。

      • 这样,针对第一个例子, T(n)= 4 n2 - 2n + 2,大O符号就记下剩余的部分,写作:

        • T(n) ∈ O(n2)

          或者

        • T(n) = O(n2)

  • ❣️ 我们就说该算法 具有n2 阶(平方阶)的时间复杂度,表示为O(n2)

常见的对数阶

  • 常用的函数阶
符号名称
O(1)常数(阶、下同)
O(log n)对数
O(n)线性、次线性
O(n log n)线性对数、或者对数线性、拟线性、超线性
O(n2)平方
O(n2) , Interger(c > 1)多项式,有时叫作‘代数’(阶)
O(cn)指数,有时叫作“几何”(阶)

空间复杂度

  • 空间复杂度指的是,程序运行过程中所需要的额外存储空间。

    • 空间复杂度 也可以用大O表示法来表示;
    • **空间复杂度的计算方法与时间复杂度类似,**通常需要分析程序中 需要额外分配的内存空间,如数组、变量、对象、递归调用等
  • 🌰 :举例

    • 对于一个简单的 递归算法来说,每次调用会在内存中分配新的栈帧,这些栈帧占用了额外的空间
      • 因此,该算法的空间复杂度是 O(n),其中n是递归深度
    • 而对于 迭代算法来说,在 **每次迭代中不需要分配额外的空间,**因此 其空间复杂度为O(1)
  • 当空间复杂度很大时,可能会导致内存不足,程序崩溃。

  • 在平时进行算法优化时,我们通常会进行如下考虑:

    • 使用尽量少的空间(优化空间复杂度)
    • 使用尽量少的时间(优化时间复杂度)
    • 特定情况下:使用 空间换时间或使用 时间换空间

数组和链表的对比

  • 使用大O表示法来对比一下数组和链表的时间复杂度(增删改查)
Data StructureAccessSearchInsertionDeletion
ArrayO(1)O(N)O(N)O(N)
Linked ListO(N)O(N)O(1)O(1)
  • 数组是一种连续的存储结构,通过下标可以直接访问数组中的任意元素

    • 时间复杂度: 对于数组,随机访问时间复杂度为O(1),插入和删除操作的时间复杂度为O(n)。
    • 空间复杂度:数组需要连续的存储空间,空间复杂度为 O(n)
  • 链表,是一种链式存储结构,通过指针链接起来的节点组成,访问链表中元素需要从头结点开始遍历

    • **时间复杂度:**对于链表,随机访问时间复杂度为O(n),插入和删除的时间复杂度为O(1)
    • **空间复杂度:**链表需要为每个节点分配存储空间,空间复杂度为O(n)
  • 💖 在实际开发中,选择使用数组还是链表需要根据具体应用场景来决定

    • 如果数据量不大,且需要频繁随机访问元素,使用数组可能会更好
    • 如果数据量很大,或者需要频繁插入和删除元素,使用链表可能会更好

【数据结构与算法——TypeScript】系列笔记:
1. 【数据结构与算法——TypeScript】数组、栈、队列、链表

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

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

相关文章

解决报错:Redis ERR unknown command ‘FLUSHDB‘

Redis ERR unknown command ‘FLUSHDB’ 报错信息&#xff1a; ERR unknown command flushdb ERR unknown command flushall解决方案&#xff1a; 我的redis版本是 5.0.7 修改配置文件 打开 /etc/redis/redis.conf 文件&#xff0c;将下面两行代码注释掉 rename-command…

Jenkins工具系列 —— Jenkins 安装并启动

文章目录 安装涉及相关链接选择安装Jenkins版本安装JenkinsJenkins web页面启动卸载Jenkins 安装涉及相关链接 Jenkins官网&#xff1a; https://www.jenkins.io/zh/ Jenkins下载安装步骤&#xff1a; https://www.jenkins.io/zh/download/ 安装各种版本OpenJDK&#xff1a; h…

weui cells 如何去掉边框

问题&#xff1a;weui cells 如何去掉边框 解决&#xff1a; cells通过before,after实现边框&#xff0c;不显示的话&#xff0c;在引用的页面wxss加上&#xff1a; .weui-cells:before,.weui-cells:after {border: none; }

3分钟白话RocketMQ系列—— 核心概念

白话3分钟&#xff0c;快速了解RocketMQ基础&#xff0c;包括适用场景&#xff0c;以及基本概念。 看完如果不了解&#xff0c;欢迎来打我。 关键字摘要 低延迟、高可用、高可靠、高并发 的消息中间件适合在线业务分为producer、consumer、nameserver、broker等角色另外还有主…

过程:从虚拟机上添加 git 并成功提交到 GitLab 的全过程

Ⅰ、准备工作&#xff1a; 1、Git 查看&#xff1a; 其一、命令&#xff1a;git --version // 此时就能在虚拟机环境下看到 git 的版本为: git version 2.41.0 其二、如何在虚拟机上安装 git &#xff1a; A、命令 &#xff1a; sudo apt-get install git B、然后再输入虚…

最不透明的211!大幅度扩招!但数据分析太难做了!

一、学校及专业介绍 中国传媒大学&#xff08;Communication University of China&#xff09;&#xff0c;简称“中传”&#xff0c;位于首都北京市&#xff0c;是中华人民共和国教育部直属的信息传播领域行业特色大学&#xff0c;国家“双一流”建设高校&#xff0c;国家“21…

基础篇:多线程所需知识:RAII接口模式对生产者和消费者封装以及多batch实现

我们先来弄一个最基础的infer类&#xff1a; class Infer{ public: bool load_model(const string &file){context_ file;return true;} void forward(){if(context_.empty()){printf("加载模型异常\n");return;}printf("使用%s进行推理\n " , contex…

学会这样提问,你就超过了82.7%的老网工

下午好&#xff0c;我的网工朋友 很多朋友会说&#xff0c;我怎么问问题&#xff0c;在群里&#xff0c;或者后台&#xff0c;还有给老杨总发消息&#xff0c;都没收到比较详细的回复&#xff1f;尤其是问技术问题的时候。 除了我们回复消息的时间和精力的确比较有限之外&…

解密外接显卡:笔记本能否接外置显卡?如何连接外接显卡?

伴随着电脑游戏和图形处理的需求不断增加&#xff0c;很多笔记本电脑使用者开始考虑是否能够通过外接显卡来提升性能。然而&#xff0c;外接显卡对于笔记本电脑是否可行&#xff0c;以及如何连接外接显卡&#xff0c;对于很多人来说仍然是一个迷。本文将为您揭秘外接显卡的奥秘…

【Linux】编写shell脚本将项目前一天打印的日志进行提取,并且单独保存

业务场景&#xff1a;又到了熟悉的业务场景环节&#xff0c;其实应用上有很多&#xff0c;我们为了方便提取日志中部分关键的内容&#xff0c;对接给其他人也好&#xff0c;方便自己统计也罢&#xff0c;都会比每次我们都去服务器上及时查看&#xff0c;或者下载全部日志再筛选…

单价20块蓝牙耳机卖爆越南市场,现象级爆款出现?

以儒道为文化底蕴的越南&#xff0c;是与中国最为相近的东南亚国家&#xff0c;"快速增长的劳动人口相对年轻的社会群体"是很多人对越南这个国家的基本认知。背靠庞大的Z世代用户群体&#xff0c;越南社会年轻化消费需求暴涨&#xff0c;手机与数码品类商品作为“年轻…

Linux中使用verdaccio 搭建私有npm 服务器

安装verdaccio npm i -g verdaccio安装完成 输入verdaccio,出现下面信息代表安装成功&#xff0c;同时输入verdaccio后verdaccio已经处于运行状态&#xff0c;当然这种启动时暂时的&#xff0c;我们需要通过pm2让verdaccio服务常驻 ygiZ2zec61wsgbo9t9i346jbZ:~$ verdacciowar…

Vue使用QuillEditor富文本编辑器问题记录

1.内容绑定的问题 绑定内容要使用 v-model:content"xxx" 的形式。 2.设置字体字号 字体以及字号大小的设置需要先注册。 <script> import { QuillEditor,Quill } from vueup/vue-quill import vueup/vue-quill/dist/vue-quill.snow.css; // 设置字体大小 c…

随机验证码vue实现,登录验证码随机验证码数字和字母类型的

1、组件 <!--loginCode登录验证码组件--> <template> <canvas id"canvasCode" :width"contentWidth" :height"contentHeight" /> </template> <script> export default { name: LoginCode, props: { identif…

Elasticsearch和Kibana的安装及验证

金翅大鹏盖世英&#xff0c;展翅金鹏盖世雄。 穿云燕子锡今鸽&#xff0c;踏雪无痕花云平。 ---------------- 2023.7.31.101 ----------------- 本文密钥&#xff1a;365 Elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎&#xff0c;常用来进行全文检索、…

c语言指针的运算

1、通过指针计算数组的元素&#xff08;指针相减&#xff0c;类型需要一致&#xff09;&#xff0c;比如数组元素指针相减得到的是中间相差的元素个数&#xff0c;可以用于计算数组元素的个数等 #include "stdio.h" #include <stdlib.h>int main() {int a[10]…

【树状数组】讲解

一.介绍 树状数组&#xff08;Fenwick Tree&#xff09;&#xff0c;也称为二叉索引树&#xff08;Binary Indexed Tree&#xff0c;BIT&#xff09;&#xff0c;是一种用于高效处理动态数组前缀和的数据结构。它可以在O(log n)的时间复杂度内完成单点更新和区间查询操作。 树…

前端面试的游览器部分(5)每篇10题

41.什么是浏览器的同步和异步加载脚本的区别&#xff1f;你更倾向于使用哪种方式&#xff0c;并解释原因。 浏览器的同步和异步加载脚本是两种不同的脚本加载方式&#xff0c;它们的主要区别在于加载脚本时是否阻塞页面的解析和渲染。 同步加载脚本&#xff1a; 同步加载脚本…

C# Blazor 学习笔记(3):路由管理

文章目录 前言路由管理App.razor设置登录页面设置空布局 前言 我们知道使用Blazor的官方模板&#xff0c;我们会自动得到一个拥有侧边栏的布局页面。但是我们发现我们所有新建的页面都有侧边栏。有时候我们需要跳出这个布局&#xff0c;比如我要做登录页面的时候&#xff0c;我…

【机密计算标准解读】 基于TEE的安全计算(IEEE 2952)

目录 1.概述2.定义、术语、缩略语3.技术框架3.1 架构框架3.2 分层功能4.基础组件4.1 基础层4.2 平台层4.3 应用层4.4 服务层4.5 交叉层5.安全计算参考过程6.技术和安全要求6.1 隔离要求6.2 互操作要求6.3 性能要求6.4 可用性要求6.5 数据安全要求6.6 密码学要求 1. 概述 随着…