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

news2024/11/13 15:53:07

一、数组

数组是一种线性数据结构,它是由一组连续的内存单元组成的,用于存储相同类型的数据。在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); // 添加节点 3

console.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.coloradmin.cn/o/1808401.html

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

相关文章

Java 期末复习 习题集

💖 单选题 💖 填空题 💖 判断题 💖 程序阅读题 1. 读代码写结果 class A {int m 5;void zengA(int x){m m x;}int jianA(int y){return m - y;} }class B extends A {int m 3;int jianA(int z){return super.jianA(z) m;} …

【内存管理】页表映射

页表的一些术语 现在Linux内核中支持四级页表的映射,我们先看下内核中关于页表的一些术语: 全局目录项,PGD(Page Global Directory) 上级目录项,PUD(Page Upper Directory) 中间目…

Python openpyxl 库使用详解

大家好,当谈论处理 Excel 文件时,Python 的 openpyxl 库无疑是一个强大而灵活的工具。无论是在数据分析、报告生成还是自动化任务中,openpyxl 都展现出了其独特的价值。本文将详细介绍 openpyxl 库的各种功能和用法,帮助读者掌握如…

在idea中创建Scala项目教程

1.下载Scala支持插件 文件-设置-插件-marketplace 搜索Scala 下载 2.创建项目 文件-新建-项目-新项目-构建系统maven 3.创建Scala目录 Scr-main(右键)-新建-目录(Scala回车键)-scala(右键)-将项目标记为-源代码根目录 4.对当前项目引入Scala支持 未添…

mysql设置允许外部ip访问,局域网IP访问

(支持MYSQL8版本) 1. 登录进入mysql;mysql -uroot -p输入密码进入 2. 输入以下语句,进入mysql库,查看user表中root用户的访问 use mysql; select host,user from user; 3. 更新user表中root用户域属性&#xff0c…

CST Studio Suite 2020 软件安装教程、安装包下载

CST Studio Suite 2020 安装教程 安装包下载 复制链接在浏览器打开 https://www.qqres.com/3150.html CST Studio Suite 是由Dassault Systmes公司开发的一套电磁场仿真软件。它应用于电子、通信、天线设计、射频与微波、电磁兼容性 (EMC)、电磁干扰 (EMI) 等领域。 CST St…

C++笔试-剑指offer

剑指offer 文章目录 剑指offer数组[数组中重复的数据 ](https://leetcode.cn/problems/find-all-duplicates-in-an-array/description/)将元素交换到对应的位置 二维数组中的查找二叉搜索树 旋转数组的最小数字二分查找 数组中出现次数超过一半的数字相互抵消 连续子数组的最大…

【Python Cookbook】S02E03 fnmatch 模块做字符串匹配

目录 问题解决方案讨论 问题 在不同的操作系统下,怎样做字符串匹配? 解决方案 fnmatch() 模块提供两个函数,fnmatch() 以及 fnmatchcase() 可以用来执行做这样的匹配。 from fnmatch import fnmatch, fnmatchcasematch_res fnmatch(foo.…

TikTok Shop账号需要防关联吗?

在TikTokShop作为新兴的电商销售渠道中,保护账号的安全和隐私,防止账号关联成为了重要的任务。为了更好地理解为何需要防关联以及如何进行防范,让我们深入探讨一下这个问题。 为什么要防关联? 1. 账号异常风险:防关联…

Nvidia/算能 +FPGA+AI大算力边缘计算盒子:桥梁结构安全监测

中国铁路设计集团有限公司(简称中国铁设),原铁道第三勘察设计院集团有限公司(铁三院),是中国国家铁路集团有限公司所属的唯一设计企业,成立于1953年,总部位于天津市,是以…

【FreeRTOS】创建第一个多任务程序

创建第1个多任务程序 韦东山 Freertos学习 第一个多任务程序创建 1. 目标 创建两个任务,任务A运行Led_Test,任务B运行LCD_Test。 硬件平台:DShanMCU-F103开发板 2. 接口函数 创建任务的API函数 不同操作系统有不同的创建API函数 FreeRTO…

2024-6-10 石群电路-28

2024-6-10,星期一,14:15,天气:晴,心情:晴。今天又是阳光明媚的一天,自从减肥成功and道家养生后,越来越感觉夏热冬冷,夏长冬藏这一自然规律了,虽然外面艳阳高照…

Capture One 23 软件安装教程、附安装包下载

Capture One Capture One 23 是一款功能极为全面的图片处理软件,为用户提供了真正的逼真色彩处理和无缝衔接的编辑体验,以及业界最快的联机拍摄功能,可以满足用户在图像创作上的所有功能,如创作全景拼接大图、高级色彩调整、遮罩…

每日5题Day20 - LeetCode 96 - 100

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;96. 不同的二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int numTrees(int n) {if(n < 2){return 1;}int[] dp new int[n 1]…

Signac|成年小鼠大脑 单细胞ATAC分析(2)

引言 在本教程中&#xff0c;我们将探讨由10x Genomics公司提供的成年小鼠大脑细胞的单细胞ATAC-seq数据集。本教程中使用的所有相关文件均可在10x Genomics官方网站上获取。 本教程复现了之前在人类外周血单核细胞&#xff08;PBMC&#xff09;的Signac入门教程中执行的命令。…

XMind v24.04.1 全功能VIP版(思维升级,效率飞跃)

软件介绍 XMind 是一款功能丰富的思维导图和创新构思工具&#xff0c;可在多个平台助力高效思考。它涵盖了从灵感触发、结构构建到演示展示的完整思维过程&#xff0c;有效提升创建思维导图的效率。这款工具适用于记录灵感、创新思维、问题解决和效率提升等多元场景&#xff0…

永久免费的iPhone,iPad,Mac,iWatch锁屏,桌面壁纸样机生成器NO.105

使用这个壁纸样机生成器&#xff0c;生成iPhone&#xff0c;iPad&#xff0c;Mac&#xff0c;iWatch锁屏&#xff0c;桌面壁纸&#xff0c;展示你的壁纸作品&#xff0c;一眼就看出壁纸好不好看&#xff0c;适不适合 资源来源于网络&#xff0c;免费分享仅供学习和测试使用&am…

内网穿透的方式有哪些——快解析的优势

外网穿透内网技术&#xff0c;即内网映射&#xff0c;是把目标本地内网地址和端口发布到互联网&#xff0c;是一种由内网开放到外网的权限操作。那么&#xff0c;内网穿透的方法有哪些呢&#xff1f;做映射外网的方法。需要结合自己本地网络环境和应用场景来实施。这里分享三种…

【Unity Shader入门精要 第13章】使用深度和法线纹理(二)

1. 再谈运动模糊 之前的文章中曾经通过保存渲染结果进行叠加的方式实现过运动模糊效果&#xff0c;下面的例子我们通过深度纹理重建世界坐标的方式来实现运动模糊&#xff1a; 首先&#xff0c;基于深度纹理重建像素的世界坐标&#xff0c;原理在【Unity Shader入门精要 第13…

LangChain开发【NL2SQL】应用

前言 关于LangGraph的简单介绍&#xff0c;请参考这篇博客&#xff1a; LangGraph开发Agent智能体应用【基础聊天机器人】-CSDN博客 对比LangChain实现NL2SQL 关于用LangChain开发NL2SQL的Agent应用&#xff0c;在这篇博客提供了完整的代码实现&#xff1a; LangChain开发…