双向链表的基本实现【数据结构与算法—TypeScript 实现】
笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程
双向链表:拥有两个指针方向的链表
DoublyNode 结构:
- prev:指向上一个节点
- value:节点值
- next:指向下一个节点
DoublyLinkedList 属性:
- head:头节点
- tail:尾节点
- length:链表长度
实现方法:
- append:尾部插入节点
- prepend:头部插入节点
- traverse:正向遍历
- postTraverse:反向遍历
- getNodeByPosition:根据索引获取节点
- insert:根据索引插入节点
- removeAt:根据索引删除节点
- Size:获取链表长度
具体代码实现:
class DoublyNode<T> {
value: T;
next: DoublyNode<T> | null = null;
prev: DoublyNode<T> | null = null;
constructor(value: T) {
this.value = value;
}
}
class DoublyLinkedList<T> {
head: DoublyNode<T> | null = null;
tail: DoublyNode<T> | null = null;
length: number = 0;
constructor() {}
// 获取链表长度
get Size(): number {
return this.length;
}
// 尾部插入节点
append(value: T): void {
const newNode = new DoublyNode(value);
if (!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail!.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
this.length++;
}
// 头部插入节点
prepend(value: T): void {
// 创建一个新节点
const newNode = new DoublyNode(value);
// 链表无数据,即 head 为空
if (!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
// 处理以前的 head
newNode.next = this.head;
this.head.prev = newNode;
// 更新 head
this.head = newNode;
}
// 链表数据增加
this.length++;
}
// 正向遍历
traverse() {
let current = this.head;
let _arr: (T | null)[] = [];
while (current) {
_arr.push(current.value);
current = current.next;
}
console.log(_arr.join(" -> "));
}
// 反向遍历
postTraverse() {
let current = this.tail;
let _arr: T[] = [];
while (current) {
_arr.push(current.value);
current = current.prev;
}
console.log(_arr.join(" -> "));
}
// 根据索引获取当前节点
getNodeByPosition(position: number): DoublyNode<T> | null {
let index = 0;
let current = this.head;
while (index++ < position && current) {
current = current.next;
}
return current;
}
// 根据索引插入元素
insert(value: T, position: number): boolean {
// 越界判断
if (position < 0 || position > this.length) return false;
// 头部插入
if (position === 0) {
this.prepend(value);
} else if (position === this.length) {
// 尾部插入
this.append(value);
} else {
// 根据 position 插入
const newNode = new DoublyNode(value);
let current = this.getNodeByPosition(position);
current!.prev!.next = newNode;
newNode.prev = current!.prev;
newNode.next = current;
current!.prev = newNode;
this.length++;
}
return true;
}
// 根据索引删除元素
removeAt(position: number): T | null {
// 1. 越界判断
if (position < 0 || position >= this.length) return null;
// 2. 合规情况分析
let current = this.head;
// 2.1 删除头部
if (position === 0) {
// 只有一个节点
if (this.length === 1) {
this.head = null;
this.tail = null;
} else {
// 多个节点
this.head = this.head!.next;
this.head!.prev = null;
}
} else if (position === this.length - 1) {
// 2.2 删除尾部
current = this.tail;
this.tail = this.tail!.prev;
this.tail!.next = null;
} else {
// 2.3 其余情况
const node = this.getNodeByPosition(position);
current = node;
node!.prev!.next = node!.next;
node!.next!.prev = node!.prev;
}
this.length--;
return current ? current.value : null;
}
}
const doublyLinkedList = new DoublyLinkedList<string>();
doublyLinkedList.append("aaa");
doublyLinkedList.append("bbb");
doublyLinkedList.append("ccc");
doublyLinkedList.insert("ddd", 0);
doublyLinkedList.removeAt(0);
doublyLinkedList.traverse();
双向链表的基本实现【数据结构与算法—TypeScript 实现】的更多相关文章
- JS数据结构与算法--双向链表
双向链表中链接是双向的:一个链向下一个元素,另一个链向上一个元素,如下图所示: 双向链表结构代码如下: class Node { constructor(element) { this.element ...
- 重读《学习JavaScript数据结构与算法-第三版》-第2章 ECMAScript与TypeScript概述
定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据 ...
- 数据结构与算法 Big O 备忘录与现实
不论今天的计算机技术变化,新技术的出现,所有都是来自数据结构与算法基础.我们需要温故而知新. 算法.架构.策略.机器学习之间的关系.在过往和技术人员交流时,很多人对算法和架构之间的关系感 ...
- 《数据结构与算法JavaScript描述》
<数据结构与算法JavaScript描述> 基本信息 作者: (美)Michael McMillan 译者: 王群锋 杜欢 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9 ...
- 面试常考的常用数据结构与算法(zz)
数据结构与算法,这个部分的内容其实是十分的庞大,要想都覆盖到不太容易.在校学习阶段我们可能需要对每种结构,每种算法都学习,但是找工作笔试或者面试的时候,要在很短的时间内考察一个人这方面的能力,把每种结 ...
- Android版数据结构与算法(一):基础简介
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 一.前言 项目进入收尾阶段,忙忙碌碌将近一个多月吧,还好,不算太难,就是麻烦点. 数据结构与算法这个系列早就想写了,一是梳理总结,顺便逼迫自己把一 ...
- Python3-Cookbook总结 - 第一章:数据结构和算法
第一章:数据结构和算法 Python 提供了大量的内置数据结构,包括列表,集合以及字典.大多数情况下使用这些数据结构是很简单的. 但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题. ...
- 数据结构与算法JS实现
行解算法题,没错,就是这么方便. 当然也可以使用 Node.js 环境来执行,具体参考Node.js官方文档即可. 二 对象和面向对象编程 js中5种数据类型,并没有定义更多的数据类型,但是运用j ...
- Linux内核中常用的数据结构和算法(转)
知乎链接:https://zhuanlan.zhihu.com/p/58087261 Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树. 链表 Linux内核代码大量使用了 ...
- Python 数据结构和算法
阅读目录 什么是算法 算法效率衡量 算法分析 常见时间复杂度 Python内置类型性能分析 数据结构 顺序表 链表 栈 队列 双端队列 排序与搜索 冒泡排序 选择排序 插入排序 希尔排序 快速排序 归 ...
随机推荐
- 【Azure 应用服务】Python Function App重新部署后,出现 Azure Functions runtime is unreachable 错误
问题描述 Python Function App重新部署后,出现 Azure Functions runtime is unreachable 错误 问题解答 在Function App的门户页面中, ...
- Spring Boot+Thymeleaf+MyBatis--推荐一个后端练手极佳的商城项目
项目整体架构 newbee-mall ├── src/main/java └── ltd.newbee.mall ├── common // 存放相关的常量配置及枚举类 ├── config // 存 ...
- 什么是Redis持久化?
Redis持久化指的是将内存中的数据同步到硬盘文件,并在redis重新启动的时候将数据备份到硬盘上,从而保证数据的安全性.通过持久化, Redis可以在系统关闭时将数据保存到硬盘上,避免了数据丢失的风 ...
- Codeforces Round 920 (Div. 3)(A~F)
目录 A B C D E F A 按题意模拟即可 #include <bits/stdc++.h> #define int long long #define rep(i,a,b) for ...
- 什么是docker的多阶段构建
Docker多阶段构建是一种技术,允许在不同的构建阶段中使用不同的基础镜像,并只复制构建所需的文件和依赖项.这种技术旨在减少最终生成的Docker镜像的大小和运行时的资源消耗. 多阶段构建的一般工作流 ...
- STM32 USB协议和代码分析
一 前言: usb接口是一个非常重要的通信接口,它的协议是有些复杂的.作为一个工程师,对usb协议和代码进行分析,是一个必备的素质和技能.最近一个项目用到了USB存储接口,花了不少时间把项目做完之后, ...
- 为aws中国配置docker镜像加速
在AWS中国,docker镜像基本无法拉取,更换国内镜像是必须的. 修改docker配置文件 sudo vi /etc/sysconfig/docker 找到OPTIONS参数,在后面加上" ...
- kettle多个表一起迁移-通过配置文件配置需要同步的字段,非全字段同步
kettle多个表一起迁移-通过配置文件配置需要同步的字段,非全字段同步 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章, 关注回复「999」获取本例源文件, 免费领取全网最热的 ...
- day04-应用线程03
JavaGUI-坦克大战04 7.线程的应用03 7.3坦克大战4.0版 7.3.4功能3:敌方坦克自由移动 功能3:让敌人的坦克也可以自由随机地上下左右移动 思路: 因为要求敌人的坦克自由移动,因此 ...
- 32_音视频播放器_SDL播放
目录 一.简介 二.音频重采样 2.1 引入头文件 2.2 定义重采样相关属性 2.3初始化重采样 2.4 重采样 三.SDL播放 四.停止功能 五.处理读完音频包的情况 六.实现调节音量 七.实现静 ...