[数据结构学习笔记4] 链表

news/2025/1/7 7:15:11/文章来源:https://www.cnblogs.com/Eagle6970/p/18652418

链表(Linked Lists)

和数组类似,链表也是用来存放一组数据。和数组不一样的是,链表存储不需要连续的内存位置,一个链表由很多节点组成,节点与节点间通过一个next 指针关联。

图示:

Node
Value / Data Next

 

链表操作:

查找一个值:

通过链表的next 指针一直往下跳直到:

1. 找到了想要的值;

2. 到达最后一个节点了。

添加节点:

1. 添加在末尾:将末尾节点的next指针指向新加节点;

2. 添加在中间(如C, D 中间):将C的next 指针指向新节点,将新节点的next指向D。

删除节点:

1. 删除的是尾部节点:将尾部前一个节点的next置空;

2. 删除的是中间节点:将删除节点的前一个节点的next指向删除节点的next,将删除节点的next置空。

删除节点会被垃圾回收清除。

 

时间复杂度

动作 最佳 平均 最差
查询 (Search) O(1) O(n) O(n)
添加/插入 (Add/Insert) O(1) O(n) O(n)
删除(Delete) O(1) O(n) O(n)

链表的变种:

1. 最常见的,也是上面讨论的,单向链表;

2. 双向链表,可以往两个方向遍历;

3. 环形链表,末尾next指向头节点;

4. 跨度链表,next指向后续节点有不同的步数,基本的是1步,可以有多层如2步,3步等。这种链表可以加快遍历。

 

代码实现,javascript

包含下面的实现:创建一个新的链表;往头部加一个节点;往尾部加一个节点;在某节点前加一个节点;在某节点后加一个节点;查看链表是否包含某个值;移除第一个节点;移除最后一个节点;移除某个特定的节点;将链表转化为数组;获得链表的长度。

class LinkedListNode {constructor (data, next = null) {this.data = data;this.next = next;              }  
}class LinkedList {constructor() {this.head = null;this.tail = null;this.size = 0;  }  addFirst(data) {const newNode = new LinkedListNode(data, this.head);this.head = newNode;if (!this.tail) {this.tail = newNode;}  this.size++;  
}addLast(data) {const newNode = new LinkedListNode(data);if (!this.head) {this.head = newNode;this.tail = newNode;} else {this.tail.next = newNode;this.tail = newNode;}  this.size++;
}addBefore(beforeData, data) {const newNode = new LinkedListNode(data);if (this.size === 0)
{
this.head = newNode;
this.size ++;
return;
}
if (this.head.data === beforeData) {
newNode.next = this.head;
this.head = newNode;
this.size ++;
return;
}
let current = this.head.next;
let prev = this.head;
while (current) {
if (current.data === beforeData) {
newNode.next = current;
prev.next = newNode;
this.size ++;
return;
}
prev = current;
current = current.next;
}
throw new Error(`Node with data '${beforeData}' not found in list.`); }

addAfter(afterData, data) {
const newNode = new LinkedListNode(data);

if (this.size === 0) {
this.head = newNode;
this.size ++;
return;
}

let current = this.head;
while (current) {
if (current.data === afterData) {
newNode.next = current.next;
current.next = newNode;
this.size ++;
return;
}
current = current.next;
}

throw new Error(`Node with data '${afterData}' not found in the list.`);
}

contains(data) {
  let current = this.head;
while (current) {
if (current.data === data)
return true;
current = current.next;
}
return false;
}

removeFirst() {
  if (!this.head) {
throw new Error('List is empty.');
}
this.head = this.head.next;
if (!this.head) {
this.tail = null;
}
this.size --;
}

removeLast() {
  if (!this.tail)
throw new Error('List is empty');

if (this.head === this.tail) {
this.head = null;
this.tail = null;
this.size --;
return;
}
let current = this.head;
let prev = null;
while (current.next) {
prev = current;
current = current.next;
}
prev.next = null;
this.tail = prev;
this.size --;
}

remove(data) {
  if (this.size === 0) {
throw new Error("List is empty.");
}

if (this.head.data === data) {
this.head = this.head.next;
this.size --;
return;
}

let current = this.head;
while (current.next) {
if (current.next.data === data) {
current.next = current.next.next;
this.size --;
return;
}
current = current.next;
}
throw new Error(`Node with data '${data}' not found in list.`);
}

toArray() {
  const arr = [];
let current = this.head;
while (current) {
arr.push(current.data);
current = current.next;
}
return arr;
}

getLength() {
  return this.size;
}

}

 测试上面的方法:

let letters = new LinkedList();letters.addLast("A");
letters.addLast("B");
letters.addLast("C");
letters.addLast("D");
letters.addLast("E");console.log(letters.toArray()); // [‘A’, 'B', 'C', 'D', 'E']

letters.addFirst("AA");
letters.addLast("Z");letters.remove("C");
letters.removeFirst();
letters.removeLast();letters.addAfter("D", "Q");

 

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

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

相关文章

sql server版本太老,java客户端连接失败问题定位

背景 最近半路接手了一个系统的优化需求,这个系统有个遗留问题还没解决,随着新需求的上线,系统正式开放使用,这个遗留问题也必须解决。 这个系统大概是下面这样的,支持录入各种数据源的信息(ip、端口、数据库种类、账号密码等):录入完成后,可以查看这些数据源中的表、…

深入探索 Kubernetes:从基础概念到实战运维

前言:在当今数字化转型的浪潮中,Kubernetes 已然成为云原生应用部署与管理的核心力量。无论是初创企业寻求敏捷开发,还是大型企业应对复杂业务架构,掌握 Kubernetes 都能为你的技术之旅赋能。今天,就让我们一同深入 Kubernetes 的奇妙世界,揭开它神秘的面纱,从基础概念到…

Python 将html格式书签转为excel

1.导出html格式书签2.对数据做处理 提取 <a></a> 标签 可以用vscode正则替换 <a></a> 标签的ICON属性ICON=".*"3.安装python pip替换成清华镜像 4.描述问题生成代码 import pandas as pd from bs4 import BeautifulSoup from datetime i…

UML之发现用例

用例是最简单的UML元素,用例图是最简单的UML图,但它也可能是UML中最有用的元素之一。尽管我们用包将工作分解为工作包、团队任务或单项任务,也就是说包是组织UML中的各种图及元素的工具。但是用例图可以帮助我们确定任务,以及应当如何将它们分组并确定工作范围。 每个用例都…

遗留了很久的功能终于搞定/QTreeWidget自定义节点/添加删除修改分组

一、前言说明 这个功能看起来简单,实际上也确实简单,以前没搞的时候还以为很难,难点就是如何存储这个任意层级的树状列表信息,近期大环境经济很差,刚好有空把这个功能搞定,其实二维表格的方式存储这种任意层级树结构就可以,就是子节点需要指定父节点,父节点为空表示顶层…

2025年正在重塑行业的10款AI代理工具

序言:本文的作者列出来的这10款AI代理工具是您认可的吗? 作为一名深入AI开发领域超过十年的开发者,我见过无数工具声称要颠覆我们构建AI代理的方式。有些工具确实实现了夸下的海口——但更多的则没有。 经过几个月的亲身测试以及与同行开发者的讨论,我整理出了一份2025年真…

[cause]: TypeError: e_.createContext is not a function (Next.js 15)

开发 Next.js 项目遇到报错: [cause]: TypeError: e_.createContext is not a function 出现这个报错的原因是在 Next.js 项目中,在 Server Component 中使用了MUI组件,但是MUI组件没有做 SSR 适配就会导致这个报错。 解决办法 解决办法就是在文件顶部添加 use client 声明…

golang自带的死锁检测并非银弹

网上总是能看到有人说go自带了死锁检测,只要有死锁发生runtime就能检测到并及时报错退出,因此go不会被死锁问题困扰。 这说明了口口相传知识的有效性是日常值得怀疑的,同时也再一次证明了没有银弹这句话的含金量。 这个说法的杀伤力在于它虽然不对,但也不是全错,真真假假很…

2025多校冲刺省选模拟赛2

2025多校冲刺省选模拟赛2\(T1\) A. aw \(10pts/20pts\)部分分\(10 \sim 20pts\) :枚举每一种定向方案,略带卡常。点击查看代码 const int p=998244353; struct node {int nxt,to; }e[200010]; int head[100010],dis[1010][1010],a[100010],b[100010],g[2][100010],cnt=0; b…

jamovi 2.6 (Linux, macOS, Windows) - 统计软件

jamovi 2.6 (Linux, macOS, Windows) - 统计软件jamovi 2.6 (Linux, macOS, Windows) - 统计软件 open statistical software 请访问原文直链:https://sysin.org/blog/jamovi/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.orgjamovi适用于桌面和云的开放式统计软…

读数据保护:工作负载的可恢复性26商用数据备份方案

商用数据备份方案1. 备份简史 1.1. 20世纪80年代中期大家都还没有意识到,运行着商用UNIX操作系统的大型工作环境里,应该配备一款商用的备份软件或某种自动的磁带系统 1.2. 1993年备份工作全都是通过shell脚本与cron job形式的计划任务来实现的1.2.1. 脚本总是假定服务器中需要…

OpenCV和OpenVX有什么联系和区别

OpenCV和OpenVX有什么联系和区别 联系和区别是:OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库。OpenVX 实现了跨平台加速处理,OpenVX在嵌入式和实时性系统中,可以更好地发挥它的优势,在某些场合配合OpenCV的强大功能,可以实现更好的效果。…