数据结构和算法之数组和链表

一、数组

数组是一种线性数据结构,它是由一组连续的内存单元组成的,用于存储相同类型的数据。在JavaScript中,数组可以包含任意类型的数据,不只限于基本数据类型。

1.存储方式

在内存中,数组的元素是连续存储的,通过下标来访问数组中的元素。例如,一个包含整型数据的数组可以用类似以下方式来表示:

let arr = [1, 2, 3, 4, 5];

2.访问方式

通过数组下标来访问数组中的元素,数组下标从0开始。例如,要访问数组中的第三个元素,可以使用以下方式:

console.log(arr[2]); // 输出3

3.时间复杂度

  • 访问:由于数组中的元素是连续存储的,通过下标访问数组中的元素的时间复杂度是O(1)。因为可以直接通过下标计算出元素的内存地址。

4.插入删除操作的复杂度

-== 插入和删除操作对数组的时间复杂度为O(n)==。因为在插入或删除一个元素时,需要将数组中的元素进行移动以保持元素的连续性,这将导致额外的时间开销。例如,在数组的开头插入一个元素将需要将之后的元素全部向后移动一个位置,这将是一个线性操作。

综上所述,数组是一种灵活的数据结构,可以用于存储和访问大量元素。访问操作的时间复杂度是固定的O(1),但插入和删除操作的时间复杂度取决于操作的位置,可能是O(n)。

二、链表

链表是一种数据结构,它由多个节点组成,每个节点包含数据和指向下一个节点的指针。

从存储方式来看,链表的节点是通过指针相连接的方式存储在内存中。每个节点都包含一个指针,指向下一个节点的地址,这样就形成了节点之间的连接。

举例来说,可以用JavaScript实现一个简单的链表节点:

class Node {constructor(data) {this.data = data;this.next = null;}
}

接着可以创建一个链表, 将多个节点连接起来:

let node1 = new Node(1);
let node2 = new Node(2);
node1.next = node2;

从访问方式来看,链表的访问是通过依次遍历节点来访问元素的。为了访问特定位置的元素,需要从链表的头节点开始顺着指针找到对应位置的节点。

访问链表的时间复杂度为O(n),其中n为链表的长度

对于插入和删除操作,链表的复杂度取决于要插入或删除的位置。如果要在链表头部插入或删除元素,时间复杂度为O(1);如果要在链表尾部插入或删除元素,仍然是O(n)。

综上所述,链表是一种灵活的数据结构,适合频繁进行插入或删除操作。

三、数组和链表的区别

数组和链表是两种常见的数据结构,它们之间的主要区别在于数据的存储方式和访问方式。

1. 存储方式:

  • 数组是一种连续的内存结构,所有元素在内存中相邻存储。数组的大小在创建时就确定了,可以通过下标来访问任意位置的元素。
  • 链表是一种非连续的内存结构,元素在内存中通过指针相连。链表的大小可以动态增长或减少,每个节点保存了下一个节点的指针,通过遍历来访问元素。

2. 访问方式:

  • 数组的元素可以直接通过下标来访问,时间复杂度为O(1)。但插入或删除元素时,需要移动其他元素,时间复杂度为O(n)。
  • 链表的元素需要通过遍历从头节点开始找到目标节点,时间复杂度为O(n)。但插入或删除元素时,只需要修改指针,时间复杂度为O(1)。

综上所述,数组适合需要频繁随机访问元素的情况,而链表适合需要频繁插入、删除元素的情况。在实际应用中,我们根据具体的需求选择不同的数据结构。

四、用js实现链表

// 定义节点类
class Node {// 节点类构造函数,接收数据作为参数constructor(data) {this.data = data; // 节点存储的数据this.next = null; // 指向下一个节点的指针}
}// 定义链表类
class LinkedList {// 链表类构造函数constructor() {this.head = null; // 链表的头节点}// 添加节点到链表末尾append(data) {let newNode = new Node(data); // 创建新节点if (this.head === null) { // 如果链表为空this.head = newNode; // 新节点就是头节点} else { // 如果链表不为空let current = this.head; // 从头节点开始while (current.next !== null) { // 遍历链表current = current.next; // 移动到下一个节点}current.next = newNode; // 将新节点添加到链表末尾}}// 删除指定值的节点delete(data) {if (this.head === null) { // 如果链表为空return; // 直接返回}if (this.head.data === data) { // 如果头节点就是要删除的节点this.head = this.head.next; // 头节点指向下一个节点return;}let current = this.head; // 从头节点开始let prev = null; // 记录当前节点的前一个节点while (current !== null) { // 遍历链表if (current.data === data) { // 如果找到要删除的节点prev.next = current.next; // 前一个节点指向当前节点的下一个节点return;}prev = current; // 记录当前节点current = current.next; // 移动到下一个节点}}// 查找指定值的节点find(data) {let current = this.head; // 从头节点开始while (current !== null) { // 遍历链表if (current.data === data) { // 如果找到指定值的节点return current; // 返回该节点}current = current.next; // 移动到下一个节点}return null; // 如果没有找到,返回 null}// 修改指定节点的值update(data, newData) {let node = this.find(data); // 查找指定值的节点if (node !== null) { // 如果找到该节点node.data = newData; // 修改该节点的值}}// 打印链表print() {let current = this.head; // 从头节点开始let arr = [];while (current !== null) { // 遍历链表arr.push(current.data); // 将节点的数据添加到数组中current = current.next; // 移动到下一个节点}console.log(arr.join('=>')); // 打印链表}
}// 测试链表功能
let list = new LinkedList();
list.append(1); // 添加节点 1
list.append(2); // 添加节点 2
list.append(3); // 添加节点 3console.log("Initial Linked List:");
list.print(); // 打印链表list.delete(2); // 删除节点 2
console.log("After deleting '2':");
list.print(); // 打印链表list.update(3, 4); // 将节点 3 的值修改为 4
console.log("After updating '3' to '4':");
list.print(); // 打印链表let newNode = new Node(1); 
console.log(newNode); // 输出 Node { data: 1, next: null }

在这里插入图片描述

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

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

相关文章

【Vue】组件的存放目录问题

注意: .vue文件 本质无区别 组件分类 .vue文件分为2类,都是 .vue文件(本质无区别) 页面组件 (配置路由规则时使用的组件)复用组件(多个组件中都使用到的组件) 存放目录 分类开来的…

Llama模型家族之拒绝抽样(Rejection Sampling)(二)均匀分布简介

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (一) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (二) 基于 LlaMA 3 LangGraph 在windows本地部署大模型 (三) 基于 LlaMA…

ssti模板注入

一、Flask应用 1、介绍 定义 Flask:是一个使用Python编写的轻量级web应用框架。Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。 特点 良好的文档、丰富的插件、包含开发服务器和调试器、集成支持单元测试、RESTful请求调度、支持安全cookies、基于Unicode。 …

手机短信删除怎么恢复?快速找回的3个秘密武器

手机,这个我们每天离不开的小玩意儿,有时候也会让我们头疼不已。比如,你一不小心,或者为了清理点空间,就把那些重要的短信给删了。这些短信可能是你和好友的深夜聊天,或者是重要的工作信息。一旦删除&#…

人工智能就业方向有哪些?

人工智能就业方向有哪些? 随着人工智能技术的不断发展,其应用领域也越来越广泛。对于想要进入人工智能领域的年轻人来说,选择一个合适的职业方向是至关重要的。今天给大家介绍六个热门的人工智能就业方向,分别是机器学习工程师、自然语言处理…

Webshell检测初识

最近在研究webshell检测的小东西,所以开启一个专门记录webshell检测工具开发的专栏,若有遗漏之处,请大佬们指出。 本篇大致了解以下内容 什么是webshll?有哪些类型?各自有什么不同?Webshell有哪些常见的检测…

鼠标侧键映射虚拟桌面切换 —— Win11

鼠标侧键映射虚拟桌面切换 —— Win11 基于 AutoHotkey 实现功能 下载软件 AutoHotkey建议安装在默认路径下(C盘) 此软件非常小,几乎不占用资源软件安装在默认路径以外的位置可能导致部分功能不可用 新建一个 .ahk 文件使用记事本打开该 .a…

哪款开放式耳机佩戴最舒服?2024五款备受推崇产品分享!

​在现今耳机市场,开放式耳机凭借其舒适的佩戴体验和独特的不入耳设计,备受消费者追捧。它们不仅让你在享受音乐时,仍能察觉周围的声音,确保与人交流无障碍,而且有利于耳朵的卫生与健康。对于运动爱好者和耳机发烧友而…

GIGE 协议摘录 —— 引导寄存器(四)

系列文章目录 GIGE 学习笔记 GIGE 协议摘录 —— 设备发现(一) GIGE 协议摘录 —— GVCP 协议(二) GIGE 协议摘录 —— GVSP 协议(三) GIGE 协议摘录 —— 引导寄存器(四) GIGE 协议…

Flutter Dismissible 属性介绍及使用指南

在移动应用开发中,滑动删除是一种常见的交互方式。Flutter 提供了一个强大的小部件 Dismissible,使得实现这一功能变得非常简单。本文将介绍 Dismissible 的主要属性及其使用方法。 1. Dismissible 简介 Dismissible 是一个 Flutter 小部件&#xff0c…

前后端实现文件上传进度条-实时进度

后端接口代码&#xff1a; PostMapping("/upload")public ResponseEntity<String> handleFileUpload(RequestParam("file") MultipartFile file) {try {// 获取文件名String fileName file.getOriginalFilename();// 创建上传目标路径Path targetPa…

基于简单Agent对医疗数据进行分析

数据表 供应商资格审核规定.pdf 医生名录.xlsx 历史就诊记录.xlsx 患者信息名录.xlsx 药品.xlsx 药品库存管理.xlsx 采购单位基本信息.xlsx Agent测试 模型基于ChatGPT-3.5 问题&#xff1a;帮我找出不达标的供应商 Agent分析过程 [Thought: 0] Key Concepts: - 不达标的供…

P7 品牌管理

逆向生成页面 新增菜单—商品系统的品牌管理 —product/brand 在代码生成器得到的文件中&#xff0c; main-resources-src-views-modules-product brand.vue、brand-add-or-update.vue放到category.vue同级vue文件有新增、删除按钮&#xff0c;但页面未显示&#xff0c;是因…

嵌入式Linux系统中RTC应用的操作详解

第一:RTC的作用以及时间简介 “RTC”的英文全称是Reul-Time Clock,翻译过来是实时时钟芯片.实时时钟芯片是日常生活中应用最为广泛的电子器件之一,它为人们或者电子系统提供精确的实时时间,实时时钟芯片通过引脚对外提供时间读写接口,通常内部带有电池,保证在外部系统关…

【Android】使用EventBus进行线程间通讯

EventBus 简介 EventBus&#xff1a;github EventBus是Android和Java的发布/订阅事件总线。 简化组件之间的通信 解耦事件发送者和接收者 在 Activities, Fragments, background threads中表现良好 避免复杂且容易出错的依赖关系和生命周期问题 Publisher使用post发出…

好书推荐-人工智能数学基础

本书以零基础讲解为宗旨&#xff0c;面向学习数据科学与人工智能的读者&#xff0c;通俗地讲解每一个知识点&#xff0c;旨在帮助读者快速打下数学基础。    全书分为 4 篇&#xff0c;共 17 章。其中第 1 篇为数学知识基础篇&#xff0c;主要讲述了高等数学基础、微积分、泰…

鸿蒙Ability Kit(程序框架服务)【应用启动框架AppStartup】

应用启动框架AppStartup 概述 AppStartup提供了一种更加简单高效的初始化组件的方式&#xff0c;支持异步初始化组件加速应用的启动时间。使用启动框架应用开发者只需要分别为待初始化的组件实现AppStartup提供的[StartupTask]接口&#xff0c;并在[startup_config]中配置App…

Open vSwitch 数据包处理流程

一、Open vSwitch 数据包转发模式 Open vSwitch 根据不同的模块使用&#xff0c;主要分为两种数据包的转发模式&#xff1a;Datapath 模式和 DPDK 模式&#xff0c;这两种模式的主要区别在于&#xff1a; Datapath 模式&#xff1a; 使用内核空间的网络栈进行数据包的转发性能相…

理解和实现 LRU 缓存置换算法

引言 在计算机科学中&#xff0c;缓存是一种用于提高数据访问速度的技术。然而&#xff0c;缓存空间是有限的&#xff0c;当缓存被填满时&#xff0c;就需要一种策略来决定哪些数据应该保留&#xff0c;哪些应该被淘汰。LRU&#xff08;最近最少使用&#xff09;算法是一种广泛…

UML实现图-部署图

概述 部署图(Deployent Diagram)描述了运行软件的系统中硬件和软件的物理结构。部署图中通常包含两种元素:节点和关联关系&#xff0c;部署图中每个配置必须存在于某些节点上。部署图也可以包含包或子系统。 节点是在运行时代表计算机资源的物理元素。节点名称有两种:简单名和…