链表
// import { defaultEquals } from "./util"; // import { Node } from "./link-list-models"; // {1} class Node { constructor(element){ this.element = element; // 表示要加入链表元素的值; this.next = undefined; // 指向链表中下一个元素的指针 } } function defaultEquals(a, b) { return a === b; // 作为默认的相等性比较函数 } class LinkedList { constructor(equalsFn = defaultEquals) { this.count = 0; // 存储链表中的元素数量 this.head = undefined; // {3} this.equalsFn = equalsFn; // 比较链表中的元素是否相等 {4} } /* 由于该数据结构是动态的,我们还需要将第一个元素的引用保存下来。我们可以用一个叫作head 的元素保存引用(行{3}) 要表示链表中的第一个以及其他元素,我们需要一个助手类,叫作 Node(行{1}) 要比较链表中的元素是否相等,我们需要使用一个内部调用的函数,名为 equalsFn(行{4}) */ // 向链表尾部添加元素 push(element) { const node = new Node(element); let current; if (this.head == null) { this.head = node; } else { 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 = current.next; } else { // let previous; // for (let i = 0; i < index; i++) { // previous = current; // current = current.next; // } /* 使用getElementAt重构遍历方法 */ const previous = this.getElementAt(index - 1); current = previous.next; // 将previous与current的下一项链接起来;跳过current,从而移除它 previous.next = current.next; } this.count--; return current.element; } return undefined; } // 循环迭代链表直到目标位置 getElementAt(index) { if (index >= 0 && index <= this.count) { let node = this.head; for (let i = 0; i < index && node != null; i++) { node = node.next; } return node; } return undefined; } // 在任意位置插入元素 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.getElementAt(index - 1); const current = previous.next; node.next = current; previous.next = node; } this.count++; return true; } return false; } // indexOf 方法:返回一个元素的位置 indexOf(element) { let current = this.head; for (let i = 0; i < this.count && current != null; i++) { if(this.equalsFn(element, current.element)) { return i; } current = current.next; } return -1; } // 根据元素--- 从链表中移除元素 remove(element) { const index = this.indexOf(element); return this.removeAt(index); } size(){ return this.count; } isEmpty() { return this.size() === 0; } getHead(){ return this.head; } // toString 方法 toString() { if(this.head == null) { return ''; } let objString = `${this.head.element}`; let current = this.head.next; for (let i = 0; i < this.size() && current != null; i++) { objString = `${objString},${current.element}`; current = current.next; } return objString; } } const list = new LinkedList(); list.push(15); list.push(20); console.log(list); // 移除 // setTimeout(function(){ // let remoele = list.removeAt(1); // console.log('移除的元素',remoele); // console.log(list); // },5000) list.insert(55,1) console.log(list); let tostring = list.toString(); console.log(tostring);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?