实现双向链表

假设理解 big o 表示法。 javascript 中有示例。资料参考 gayle laakmann mcdowell 的《cracking the coding interview》
理解双向链表
双向链表与单链表非常相似,除了节点的结构和添加/删除节点的方式不同。
节点结构双向链表中的节点包含
prev指针、next指针和value。 prev 指针指向前一个节点,next 指针指向下一个节点。本质上,这个列表在每个节点都是双向的。
添加节点在特定索引处插入新节点(newnode):
- 将当前位于插入索引处的节点存储在临时变量 nextnode 中。
- 更新前一个节点和新节点的连接:
- 将前一个节点的next指针设置为newnode。
- 设置newnode的prev指针指向前一个节点。
- 将新节点连接到下一个节点:
- 将newnode的next指针设置为nextnode。
- 将 nextnode 的 prev 指针设置为 newnode。
要删除特定索引处的节点:
- 更新前一个节点的next指针:
-
- 设置为指向被移除后的节点。
更新下一个节点的prev指针:
-
- 将其设置为指向被删除节点之前的节点。
时间复杂度分析
- 在双向链表中添加/删除 →
css">o(n)
- 在双向链表的头部或尾部添加/删除 →
o(1)
经典面向对象编程
class listnode {
constructor(value, prev = null, next = null) {
this.value = value;
this.prev = prev;
this.next = next;
}
}
class doublylinkedlist {
constructor() {
this.head = null;
this.tail = null;
this.size = 0;
}
// add a node to the head of the list
addhead(value) {
const newnode = new listnode(value, null, this.head);
if (this.head) {
this.head.prev = newnode;
} else {
this.tail = newnode; // if list was empty, new node is also the tail
}
this.head = newnode;
this.size++;
}
// add a node to the tail of the list
addtail(value) {
const newnode = new listnode(value, this.tail, null);
if (this.tail) {
this.tail.next = newnode;
} else {
this.head = newnode; // if list was empty, new node is also the head
}
this.tail = newnode;
this.size++;
}
// remove a node from the head of the list
removehead() {
if (!this.head) return null; // list is empty
const removedvalue = this.head.value;
this.head = this.head.next;
if (this.head) {
this.head.prev = null;
} else {
this.tail = null; // list became empty
}
this.size--;
return removedvalue;
}
// remove a node from the tail of the list
removetail() {
if (!this.tail) return null; // list is empty
const removedvalue = this.tail.value;
this.tail = this.tail.prev;
if (this.tail) {
this.tail.next = null;
} else {
this.head = null; // list became empty
}
this.size--;
return removedvalue;
}
// remove a node at a specific index
removeat(index) {
if (index < 0 || index >= this.size) return null;
let current;
if (index < this.size / 2) {
current = this.head;
for (let i = 0; i < index; i++) {
current = current.next;
}
} else {
current = this.tail;
for (let i = this.size - 1; i > index; i--) {
current = current.prev;
}
}
if (current.prev) current.prev.next = current.next;
if (current.next) current.next.prev = current.prev;
if (index === 0) this.head = current.next;
if (index === this.size - 1) this.tail = current.prev;
this.size--;
return current.value;
}
// get the size of the list
getsize() {
return this.size;
}
// get the values in the list
getvalues() {
const values = [];
let current = this.head;
while (current) {
values.push(current.value);
current = current.next;
}
return values;
}
}
# css
相关栏目:
【
网站优化84359 】
【
站长学院75356 】
【
运营推广7218 】
【
小程序18188 】
【
运维技术36808 】
【
营销推广32536 】
【
SEO优化41416 】
【
百度推广27695 】
【
AI推广83940 】
相关推荐:
MySQL中如何使用MD5加密
centos怎么发送邮件
Centos httpd启动失败的解决方法
改变游戏规则的 Web 开发工具可在 4 年内增强您的工作流程
tp6如何使用redis缓存
Linux中MySQL日志在哪
Web 标准和最佳实践的重要性:为什么在 JavaScript 中重新发明轮子通常会导致更糟糕的解决方案
linux如何安装qq
Notepad++中localization什么意思
MySQL数据库触发器trigger怎么使用
vue3怎么使用pinia
Redis基本数据类型List常用操作命令是什么
linux怎么安装run文件
Redis入门基础常用操作命令实例分析
vue3与vue2区别
怎么用phpstorm做表格
MySQL聚合查询与联合查询操作的示例分析
redis项目的知识点有哪些
使用 Nextjs 增强 Web 性能:延迟加载、图像优化和服务器端渲染
win7停留在启动管理器进不了桌面怎么解决?
怎么查看映射docker容器的路径
js页面内跳转 js如何实现页面内部跳转方法
MySQL日期函数的使用示例
composer.json文件详解
vue3和vue2的优缺点
centOS7环境下怎么搭建安装Redis
git怎么实现用户的登录设置
Svn工具怎么安装
notepad++怎么设置黑色背景颜色
notepad怎么调字体大小
vue3与vue2区别大吗
MySQL数据库约束类型有哪些
linux如何重命名文件
零开销异步/等待
怎么查看docker镜像中的文件
linux如何查看防火墙是否关闭
vue3怎么获取this
vue3常见面试题
vue2和vue3哪个是主流
notepad++中选中行的字体背景怎么选择
notepad怎么把字体调大
Linux下怎么安装vscode
centos系统如何查看mysql是否启动
Sublime Text的快捷方式有哪些
Redis优惠券秒杀问题怎么解决
vue3的pinia有什么缺点
centos怎么挂载光盘
notepad怎么显示json数据
phpstorm在电脑上怎么下载
phpstorm怎么卸载

上一篇
