单链表封装 - 使用JavaScript封装

news2025/3/11 8:34:47

痛苦就是在蜕变吗

目录

  • 链表:
  • 链表的特点:
  • 单链表:
    • 单链表的封装- JS封装:
  • 单链表的应用:
    • 解决回文:
    • 解决击鼓传花:
    • 十进制进制转换其他进制:

链表:

链表就是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。链表由一系列结点组成,结点可以在运行时动态的生成。
每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

链表的特点:

  1. 插入、删除数据效率 O(1)级别(只需要更改指针指向即可),随机访问效率低 O(n)级别 (需要从链头至链尾进行遍历)
  2. 和数组相比,内存空间消耗更大,因为每个存储数据的节点都需要额外的空间存储后继指针。

单链表:

每个节点只包含一个指针,即后继指针。

单链表的封装- JS封装:

<script>
  class Node {
    constructor(element) {
      this.element = element;
      this.next = null;
    }
  }

  class LinkedList {
    // #
    constructor() {
      this.count = 0;
      this.head = null;
    }

    // push 添加一个节点
    push (element) {
      const node = new Node(element);

      // header是空
      if (this.head === null) {
        this.head = node;
      } else {
        let current = this.head;
        while (current.next !== null) {
          current = current.next;
        }
        current.next = node;
      }
      this.count++;
    }

    // 指定位置删除 传入索引
    removeAt (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous;
          for (let i = 0; i < index; i++) {
            previous = current;
            current = current.next;
          }
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }
    // 指定位置删除-方法二利用getNodeAt(index) 传入索引
    removeAt2 (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous = this.getNodeAt(index - 1);
          current = previous.next;
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }

    // 根据索引获得节点node
    getNodeAt (index) {
      if (index >= 0 && index < this.count) {
        let node = this.head;

        for (let i = 0; i < index; i++) {
          node = node.next;
        }
        return node;
      }
      return;
    }

    // 判断是否相等
    equalFn (a, b) {
      // 暴力写法:
      // 也有缺陷 JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})
      return JSON.stringify(a) === JSON.stringify(b);
      // 可以使用第三方库
    }

    // 根据元素返回索引
    indexOf (element) {
      let current = this.head;
      for (let i = 0; i < this.count; i++) {
        if (this.equalFn(current.element, element)) {
          return i;
        }
        current = current.next;
      }
    }

    // 直接根据值删除
    remove (element) {
      // 根据数据返回索引的方法
      const index = this.indexOf(element);
      return this.removeAt(index);
    }

    // 指定位置插入内容
    insert (element, index) {
      if (index >= 0 && index <= this.count) {
        const node = new Node(element);
        if (index == 0) {
          const current = this.head;
          node.next = current;
          this.head = node;
        } else {
          const previous = this.getNodeAt(index - 1);
          const current = previous.next;
          previous.next = node;
          node.next = current;
        }
        this.count++;
        return true;
      }
      return false;
    }

    // 判断是否为空
    isEmpty () {
      return this.size() === 0;
    }
    // 判断长度
    size () {
      return this.count;
    }

    // 返回链头
    getHead () {
      return this.head;
    }
  }

  let list = new LinkedList()
</script>

单链表的应用:

解决回文:

举个例子,当初判断回文的时候我们使用的双端队列,在这里使用单链表解决:

<script>
  class Node {
    constructor(element) {
      this.element = element;
      this.next = null;
    }
  }

  class LinkedList {
    // #
    constructor() {
      this.count = 0;
      this.head = null;
    }

    // push 添加一个节点
    push (element) {
      const node = new Node(element);

      // header是空
      if (this.head === null) {
        this.head = node;
      } else {
        let current = this.head;
        while (current.next !== null) {
          current = current.next;
        }
        current.next = node;
      }
      this.count++;
    }

    // 指定位置删除 传入索引
    removeAt (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous;
          for (let i = 0; i < index; i++) {
            previous = current;
            current = current.next;
          }
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }
    // 指定位置删除-方法二利用getNodeAt(index) 传入索引
    removeAt2 (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous = this.getNodeAt(index - 1);
          current = previous.next;
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }

    // 根据索引获得节点node
    getNodeAt (index) {
      if (index >= 0 && index < this.count) {
        let node = this.head;

        for (let i = 0; i < index; i++) {
          node = node.next;
        }
        return node;
      }
      return;
    }

    // 判断是否相等
    equalFn (a, b) {
      // 暴力写法:
      // 也有缺陷 JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})
      return JSON.stringify(a) === JSON.stringify(b);
      // 可以使用第三方库
    }

    // 根据元素返回索引
    indexOf (element) {
      let current = this.head;
      for (let i = 0; i < this.count; i++) {
        if (this.equalFn(current.element, element)) {
          return i;
        }
        current = current.next;
      }
    }

    // 直接根据值删除
    remove (element) {
      // 根据数据返回索引的方法
      const index = this.indexOf(element);
      return this.removeAt(index);
    }

    // 指定位置插入内容
    insert (element, index) {
      if (index >= 0 && index <= this.count) {
        const node = new Node(element);
        if (index == 0) {
          const current = this.head;
          node.next = current;
          this.head = node;
        } else {
          const previous = this.getNodeAt(index - 1);
          const current = previous.next;
          previous.next = node;
          node.next = current;
        }
        this.count++;
        return true;
      }
      return false;
    }

    // 判断是否为空
    isEmpty () {
      return this.size() === 0;
    }
    // 判断长度
    size () {
      return this.count;
    }

    // 返回链头
    getHead () {
      return this.head;
    }
  }
</script>
<script>
  // 使用单链表解决回文问题
  function test (str) {
    const lowstr = str.toLocaleLowerCase().split(" ").join("");

    let list = new LinkedList();

    for (let i = 0; i < lowstr.length; i++) {
      list.push(lowstr[i]);
    }
    let isEqual = true;
    while (list.size() > 1) {
      if (list.removeAt(0) !== list.removeAt(list.size() - 1)) {
        isEqual = false;
        break;
      }
    }
    return isEqual;
  }
  test("D  a   d");
</script>

解决击鼓传花:

举个例子,当初击鼓传花的时候我们使用的队列,在这里使用单链表解决:

<script>
  class Node {
    constructor(element) {
      this.element = element;
      this.next = null;
    }
  }

  class LinkedList {
    // #
    constructor() {
      this.count = 0;
      this.head = null;
    }

    // push 添加一个节点
    push (element) {
      const node = new Node(element);

      // header是空
      if (this.head === null) {
        this.head = node;
      } else {
        let current = this.head;
        while (current.next !== null) {
          current = current.next;
        }
        current.next = node;
      }
      this.count++;
    }

    // 指定位置删除 传入索引
    removeAt (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous;
          for (let i = 0; i < index; i++) {
            previous = current;
            current = current.next;
          }
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }
    // 指定位置删除-方法二利用getNodeAt(index) 传入索引
    removeAt2 (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous = this.getNodeAt(index - 1);
          current = previous.next;
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }

    // 根据索引获得节点node
    getNodeAt (index) {
      if (index >= 0 && index < this.count) {
        let node = this.head;

        for (let i = 0; i < index; i++) {
          node = node.next;
        }
        return node;
      }
      return;
    }

    // 判断是否相等
    equalFn (a, b) {
      // 暴力写法:
      // 也有缺陷 JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})
      return JSON.stringify(a) === JSON.stringify(b);
      // 可以使用第三方库
    }

    // 根据元素返回索引
    indexOf (element) {
      let current = this.head;
      for (let i = 0; i < this.count; i++) {
        if (this.equalFn(current.element, element)) {
          return i;
        }
        current = current.next;
      }
    }

    // 直接根据值删除
    remove (element) {
      // 根据数据返回索引的方法
      const index = this.indexOf(element);
      return this.removeAt(index);
    }

    // 指定位置插入内容
    insert (element, index) {
      if (index >= 0 && index <= this.count) {
        const node = new Node(element);
        if (index == 0) {
          const current = this.head;
          node.next = current;
          this.head = node;
        } else {
          const previous = this.getNodeAt(index - 1);
          const current = previous.next;
          previous.next = node;
          node.next = current;
        }
        this.count++;
        return true;
      }
      return false;
    }

    // 判断是否为空
    isEmpty () {
      return this.size() === 0;
    }
    // 判断长度
    size () {
      return this.count;
    }

    // 返回链头
    getHead () {
      return this.head;
    }
  }
</script>
<script>
  // 击鼓传花
  function game (list, num) {
    let List = new LinkedList();
    for (let i = 0; i < list.length; i++) {
      List.push(list[i]);
    }
    while (List.size() > 1) {
      for (let i = 0; i < num; i++) {
        List.push(List.removeAt(0));
      }
      console.log(List.removeAt(0), '淘汰了');
    }
    console.log('获胜的是:', List.removeAt(0));
  }

  game(['kitty', 'Alice', 'AK', 'Box', 'Whe'], 7);
</script>

在这里插入图片描述

十进制进制转换其他进制:

举个例子,当初十进制转换其他进制的时候我们使用的栈,在这里使用单链表解决:

<script>
  class Node {
    constructor(element) {
      this.element = element;
      this.next = null;
    }
  }

  class LinkedList {
    // #
    constructor() {
      this.count = 0;
      this.head = null;
    }

    // push 添加一个节点
    push (element) {
      const node = new Node(element);

      // header是空
      if (this.head === null) {
        this.head = node;
      } else {
        let current = this.head;
        while (current.next !== null) {
          current = current.next;
        }
        current.next = node;
      }
      this.count++;
    }

    // 指定位置删除 传入索引
    removeAt (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous;
          for (let i = 0; i < index; i++) {
            previous = current;
            current = current.next;
          }
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }
    // 指定位置删除-方法二利用getNodeAt(index) 传入索引
    removeAt2 (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous = this.getNodeAt(index - 1);
          current = previous.next;
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }

    // 根据索引获得节点node
    getNodeAt (index) {
      if (index >= 0 && index < this.count) {
        let node = this.head;

        for (let i = 0; i < index; i++) {
          node = node.next;
        }
        return node;
      }
      return;
    }

    // 判断是否相等
    equalFn (a, b) {
      // 暴力写法:
      // 也有缺陷 JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})
      return JSON.stringify(a) === JSON.stringify(b);
      // 可以使用第三方库
    }

    // 根据元素返回索引
    indexOf (element) {
      let current = this.head;
      for (let i = 0; i < this.count; i++) {
        if (this.equalFn(current.element, element)) {
          return i;
        }
        current = current.next;
      }
    }

    // 直接根据值删除
    remove (element) {
      // 根据数据返回索引的方法
      const index = this.indexOf(element);
      return this.removeAt(index);
    }

    // 指定位置插入内容
    insert (element, index) {
      if (index >= 0 && index <= this.count) {
        const node = new Node(element);
        if (index == 0) {
          const current = this.head;
          node.next = current;
          this.head = node;
        } else {
          const previous = this.getNodeAt(index - 1);
          const current = previous.next;
          previous.next = node;
          node.next = current;
        }
        this.count++;
        return true;
      }
      return false;
    }

    // 判断是否为空
    isEmpty () {
      return this.size() === 0;
    }
    // 判断长度
    size () {
      return this.count;
    }

    // 返回链头
    getHead () {
      return this.head;
    }
  }
</script>
<script>
  // 十进制进制转换其他进制
  function convert (decNumber, base) {
    let list = new LinkedList();
    let string = "";
    let number = decNumber;
    let baseString = "0123456789ABCDEF"

    while (number > 0) {
      list.push(number % base);
      number = Math.floor(number / base);
    }
    while (!(list.isEmpty())) {
      string += baseString[list.removeAt(list.size() - 1)];
    }
    return string;
  }
  convert(50, 8)
</script>

在这里插入图片描述

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

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

相关文章

TypeError: Cannot convert object to primitive value

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

【uniapp】图片添加canvas水印

目录 需求&背景实现地理位置添加水印 ios补充 需求&背景 需求&#xff1a;拍照后给图片添加水印, 水印包含经纬度、用户信息、公司logo等信息。 效果图&#xff1a; 方案&#xff1a;使用canvas添加水印。 具体实现&#xff1a;上传图片组件是项目里现有的&#xff…

贪吃蛇身匀速运动模型

通用运动模型 我们已知斜线为移动的距离 d d d&#xff0c; x x x轴总偏移量为 d x dx dx&#xff0c; y y y轴总偏移量为 d y dy dy&#xff0c;在一帧当中&#xff0c;我们也知道能走的距离为 m d md md。那么作为一般的运动模型&#xff0c;该如何确定我们进行移动的方向呢&…

npm 执行安装报错

Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution. 原因​ 主要的原因是 npm7 以上的版本&#xff0c;新增了一个对等依赖的特性&#xff0c;在以…

笔记五:C语言编译链接

Faye&#xff1a;孤独让我们与我们所爱的人相处的每个瞬间都无比珍贵&#xff0c;让我们的回忆价值千金。它还驱使你去寻找那些你在我身边找不到的东西。 ---------《寻找天堂》 目录 一、编译和链接的介绍 1.1 程序的翻译环境和执行环境 1.1.1 翻译环境 1.1.2 运行环境 …

【c语言概述、数据类型、运算符与表达式精选题】

c语言概述、数据类型、运算符与表达式精选题 一、易错题1.1&#x1f384; c程序的执行1.2&#x1f384; c程序的基本组成单元1.3&#x1f384; c程序的组成1.4&#x1f384; 5种基本类型数据类型长度1.5&#x1f384; C语言关键字1.6&#x1f384; 整型常量1.7&#x1f384; 合…

200个前卫街头氛围涂鸦艺术水墨颜料手绘笔迹飞溅PNG免扣迭加纹理素材 VANTABLACK TEXTURES

探索 Vantablack 200 纹理包&#xff1a;您获得前卫、高分辨率纹理的首选资源。非常适合旨在为其作品添加原始都市氛围的设计师。这些透明迭加层使用简单&#xff0c;但非常有效&#xff0c;只需单击几下&#xff0c;即可将您的设计从普通变为非凡。准备好用既酷又百搭的质地来…

深度学习模型Transformer核心组件—自注意力机制

第一章&#xff1a;人工智能之不同数据类型及其特点梳理 第二章&#xff1a;自然语言处理(NLP)&#xff1a;文本向量化从文字到数字的原理 第三章&#xff1a;循环神经网络RNN&#xff1a;理解 RNN的工作机制与应用场景(附代码) 第四章&#xff1a;循环神经网络RNN、LSTM以及GR…

nature genetics | SCENT:单细胞多模态数据揭示组织特异性增强子基因图谱,并可识别致病等位基因

–https://doi.org/10.1038/s41588-024-01682-1 Tissue-specific enhancer–gene maps from multimodal single-cell data identify causal disease alleles 研究团队和单位 Alkes L. Price–Broad Institute of MIT and Harvard Soumya Raychaudhuri–Harvard Medical S…

基于数据挖掘的疾病数据可视化分析与预测系统

【大数据】基于数据挖掘的疾病数据可视化分析与预测系统&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 &#x1f4cc; 技术核爆点&#xff1a;✔️ Python全栈开发Flask高能框架 ✔️ 爬虫技术…

《AI大模型专家之路》No.2:用三个模型洞察大模型NLP的基础能力

用三个模型洞察大模型NLP的基础能力 一、项目概述 在这个基于AI构建AI的思维探索项目中&#xff0c;我们实现了一个基于BERT的中文AI助手系统。该系统集成了文本分类、命名实体识别和知识库管理等功能&#xff0c;深入了解本项目可以让读者充分了解AI大模型训练和推理的基本原…

Spring Boot集成Minio笔记

一、首先配置MinIO 1、MinIO新建Bucket&#xff0c;访问控制台如图 创建访问密钥(就是账号和密码) 二、集成mino添加Minio客户端依赖 1.maven构建方式在pom.xml引入jar <dependency><groupId>io.minio</groupId><artifactId>minio</artifactI…

HCIA-路由重分布

一、路由重分布是指在同一个网络中&#xff0c;将一种路由协议所学习到的路由信息导入到另一种路由协议中的技术&#xff0c;实现通信。 二、实验 1、配置 AR1AR2AR3sy sy AR1 int g 0/0/1 ip add 192.168.1.254 24 int g 0/0/0 ip add 10.1.1.1 24 rip version 2 net 192.16…

【项目】nnUnetv2复现

作者提出一种nnUNet(no-new-Net)框架,基于原始的UNet(很小的修改),不去采用哪些新的结构,如相残差连接、dense连接、注意力机制等花里胡哨的东西。相反的,把重心放在:预处理(resampling和normalization)、训练(loss,optimizer设置、数据增广)、推理(patch-based…

【大学生体质】智能 AI 旅游推荐平台(Vue+SpringBoot3)-完整部署教程

智能 AI 旅游推荐平台开源文档 项目前端地址 ☀️项目介绍 智能 AI 旅游推荐平台&#xff08;Intelligent AI Travel Recommendation Platform&#xff09;是一个利用 AI 模型和数据分析为用户提供个性化旅游路线推荐、景点评分、旅游攻略分享等功能的综合性系统。该系统融合…

TCP7680端口是什么服务

WAF上看到有好多tcp7680端口的访问信息 于是上网搜索了一下&#xff0c;确认TCP7680端口是Windows系统更新“传递优化”功能的服务端口&#xff0c;个人理解应该是Windows利用这个TCP7680端口&#xff0c;直接从内网已经具备更新包的主机上共享下载该升级包&#xff0c;无需从微…

恭喜!《哪吒2》明天将荣登世界影坛第六!目前仅差1.81亿元

全球总票房为为20.27亿美元&#xff01;3月8日将荣登世界影坛第六宝座&#xff01; 中国票房 内地票房 中国电影票房、灯塔、猫眼三大数据源加权平均得出《哪吒2》中国内地总票房为144.26亿元人民币。 港澳票房 目前港澳地区没有新的数据显示&#xff0c;按3月6日1905电影网…

e2studio开发RA4M2(15)----配置RTC时钟及显示时间

e2studio开发RA4M2.15--配置RTC时钟及显示时间 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置SWD调试口设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user…

Flink深入浅出之04:时间、水印、TableSQL

深入理解Flink的waterMark的机制、Flink Table和SQL开发 3️⃣ 目标 掌握WaterMark的的原理掌握WaterMark的运用掌握Flink Table和SQL开发 4️⃣ 要点 &#x1f4d6; 1. Flink中的Time概念 对于流式数据处理&#xff0c;最大的特点是数据上具有时间的属性特征 Flink根据时…

MongoDB Compass 使用说明

MongoDB Compass 使用说明 安装工具栏按钮详细介绍Connect(连接)1. New Window&#xff08;新窗口&#xff09;2. Disconnect&#xff08;断开连接&#xff09;3. Import Saved Connections&#xff08;导入保存的连接&#xff09;4. Export Saved Connections&#xff08;导出…