当前位置: 首页 > article >正文

单链表封装 - 使用JavaScript封装

痛苦就是在蜕变吗

目录

  • 链表:
  • 链表的特点:
  • 单链表:
    • 单链表的封装- 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;}// 根据索引获得节点nodegetNodeAt (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;}// 根据索引获得节点nodegetNodeAt (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;}// 根据索引获得节点nodegetNodeAt (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;}// 根据索引获得节点nodegetNodeAt (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>

在这里插入图片描述

相关文章:

单链表封装 - 使用JavaScript封装

痛苦就是在蜕变吗 目录 链表&#xff1a;链表的特点&#xff1a;单链表&#xff1a;单链表的封装- JS封装&#xff1a; 单链表的应用&#xff1a;解决回文&#xff1a;解决击鼓传花&#xff1a;十进制进制转换其他进制&#xff1a; 链表&#xff1a; 链表就是一种物理存储单元…...

GET3D:从图像中学习的高质量3D纹理形状的生成模型

【摘要】 本文提出了GET3D,这是一种新的生成模型,能够生成具有任意拓扑结构的高质量3D纹理网格,可以直接被3D渲染引擎使用并在下游应用中立即使用。现有的3D生成模型要么缺乏几何细节,要么生成的网格拓扑受限,通常不支持纹理,或者在生成过程中使用神经渲染器,使得它们在…...

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…...

Flutter——最详细原生交互(MethodChannel、EventChannel、BasicMessageChannel)使用教程

MethodChannel&#xff08;方法通道&#xff09; 用途&#xff1a;实现 双向通信&#xff0c;用于调用原生平台提供的 API 并获取返回结果。 场景&#xff1a;适合一次性操作&#xff0c;如调用相机、获取设备信息等。 使用步骤&#xff1a; Flutter 端&#xff1a;通过 Meth…...

如何在PHP爬虫中处理异常情况的详细指南

一、常见的异常类型 在爬虫开发中&#xff0c;可能会遇到以下几种常见的异常情况&#xff1a; 网络请求失败&#xff1a;目标服务器不可用或网络连接问题。 页面结构变化&#xff1a;目标网站更新了HTML结构&#xff0c;导致选择器无法正确匹配。 反爬机制触发&#xff1a;请…...

贪吃蛇身匀速运动模型

通用运动模型 我们已知斜线为移动的距离 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;在以…...

SPA单页面应用优化SEO

1.SSR服务端渲染 将组件或页面通过服务器生成html&#xff0c;再返回给浏览器&#xff0c;如nuxt.js或vue-server-renderer const Vue require(vue); const server require(express)(); const renderer require(vue-server-renderer).createRenderer();const vueApp new …...

笔记五: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;即可将您的设计从普通变为非凡。准备好用既酷又百搭的质地来…...

机试准备第11天

第一题是浮点数加法&#xff0c;目前写过最长的代码。 #include <stdio.h> #include <string> #include <iostream> #include <vector> using namespace std; int main() {string str1;string str2;while (getline(cin, str1) && getline(cin…...

OpenIndiana Hipster系统安装配置

gcc安装 直接pkt install gcc会报错 需要 先pkt update&#xff0c;然后重启&#xff08;不重启还是报错&#xff09;用pkg search compiler找到可用的gcc包再pkt install xx安装这个包 TCP配置 参考这个网站&#xff1a;https://community.spiceworks.com/t/setting-tcp-p…...

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

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

Java核心语法:从变量到控制流

一、变量与数据类型&#xff08;对比Python/C特性&#xff09; 1. 变量声明三要素 // Java&#xff08;强类型语言&#xff0c;需显式声明类型&#xff09; int age 25; String name "CSDN"; // Python&#xff08;动态类型&#xff09; age 25 name …...

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…...

大白话如何使用 CSS 实现响应式布局?请列举一些常见的方法。

大白话如何使用 CSS 实现响应式布局&#xff1f;请列举一些常见的方法。 答题思路 首先要解释什么是响应式布局&#xff0c;让读者明白其概念和重要性。然后依次介绍常见的实现响应式布局的CSS方法&#xff0c;包括媒体查询、弹性布局&#xff08;Flexbox&#xff09;、网格布…...

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

【大数据】基于数据挖掘的疾病数据可视化分析与预测系统&#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…...

本地运行Manus的替代方案:OpenManus的技术解析与实践指南

无需邀请码&#xff0c;三小时构建的开源智能体革命 一、背景&#xff1a;从Manus到OpenManus的技术突围 近期&#xff0c;AI智能体领域因Manus的发布引发热议。这款号称“全球首个通用型AI智能体”的产品&#xff0c;通过整合浏览器操作&#xff08;Browser Use&#xff09;…...

Spring Boot整合Resilience4j教程

精心整理了最新的面试资料和简历模板&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 以下是将Spring Boot与Resilience4j整合的详细教程&#xff0c;包含基础配置和核心功能示例&#xff1a; Spring Boot整合Resilience4j教程 Resilience4j提…...

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…...

低轨卫星引爆高频PCB市场:猎板PCB的技术革新与产业机遇

一、低轨卫星产业的爆发与高频PCB需求 低轨卫星&#xff08;LEO Satellite&#xff09;因其低延迟、广覆盖的特性&#xff0c;成为全球通信网络补盲的关键技术。根据行业预测&#xff0c;到2030年&#xff0c;全球低轨卫星数量将突破5万颗&#xff0c;市场规模超千亿美元12。这…...

事件系统之如何处理用户输入和其他事件

概述 在Qt中&#xff0c;事件系统是核心机制之一&#xff0c;它允许开发者以一种灵活且高效的方式处理各种类型的事件&#xff0c;包括用户输入、窗口系统事件、定时器事件等 基本概念 事件&#xff08;Event&#xff09;&#xff1a;事件是描述应用程序状态变化的对象&…...

【项目】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电影网…...