JavaScript数据结构与算法(六) 链表的实现
// 链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个
// 元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。下图展
// 示了一个链表的结构:

// 相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然
// 而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何
// 位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到
// 所需的元素。 // 链表应用场景 火车车厢、寻宝游戏
TypeScript方式实现源码
class Node {
element;
next;
constructor(element) {
this.element = element;
this.next = null;
}
}
class LinkedList {
private length = ;
head = null;
constructor() {
}
/**
* 向列表尾部添加一个新的项
* @param element
*/
public append(element) {
let node = new Node(element), current;
if (this.head === null) {
this.head = node;
} else {
current = this.head;
// 循环列表,知道找到最后一项
while (current.next) {
current = current.next;
}
// 找到最后一项,将其next赋为node,建立链接
current.next = node;
}
this.length++; // 更新列表长度
}
/**
* 向列表的特定位置插入一个新的项
* @param position
* @param element
*/
public insert(position, element) {
// 检查越界值
if (position >= && position <= length) {
let node = new Node(element),
current = this.head,
previous,
index = ;
if (position === ) { // 在第一个位置添加
node.next = current;
this.head = node;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
node.next = current;
previous.next = node;
}
this.length++; // 更新列表长度
return true;
} else {
return false;
}
}
/**
* 从列表的特定位置移除一项
* @param position
*/
public removeAt(position) {
// 检查越界值
if (position > - && position < this.length) {
let current = this.head,
previous,
index = ;
// 移除第一项
if (position === ) {
this.head = current.next;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
// 将previous与current的下一项链接起来:跳过current,从而移除它
previous.next = current.next;
}
this.length--;
return current.element;
} else {
return null;
}
}
/**
* 从列表中移除一项
* @param element
*/
public remove(element) {
let index = this.indexOf(element);
return this.removeAt(index);
}
/**
* :返回元素在列表中的索引。如果列表中没有该元素则返回-1
* @param element
*/
public indexOf(element) {
let current = this.head,
index = -;
while (current) {
if (element === current.element) {
return index;
}
index++;
current = current.next;
}
return -;
}
/**
* 如果链表中不包含任何元素, 返回true, 如果链表长度大于0则返回false
*/
public isEmpty() {
return this.length === ;
}
/**
* 返回链表包含的元素个数。与数组的length属性类似
*/
public size() {
return this.length;
}
/**
* 由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值
*/
public toString() {
let current = this.head,
string = '';
while (current) {
string += current.element;
current = current.next;
}
return string;
}
public getHead() {
return this.head;
}
public print() {
console.log(this.toString());
}
}
// 代码解读:
// 充分利用引用对象特性,将需要管理的数据加入链表的数据结构中,
// 完全不依赖系统数组的数据结构,所以避免大量删、增数据数组排序的性能损耗。同时也失去了数组下标取数据的优势。
// 因此优势劣势非常明显,大量改删数据场景选用链表,大量已知下标去更新数据选用数组 // 抽象:
// 火车车厢可长可短,随时加入或去掉一节车厢仅仅对操作车厢前后一节有改动,当车厢非常长的时候,这个优势尤为明显,
// 这仅仅是一种应用场景也可以通过火车的例子去理解这种数据结构的设计理念 // 总结:
// 链表以引用作为媒介,将大量不相干的数据进行一个有序的链接,同时没有复杂的关联关系,仅仅关系操作数据前后关联数据
// 面对大量增加删除的场景,链表将是比数组更好的选择
var Node = (function () {
function Node(element) {
this.element = element;
this.next = null;
}
return Node;
}());
var LinkedList = (function () {
function LinkedList() {
this.length = ;
this.head = null;
}
/**
* 向列表尾部添加一个新的项
* @param element
*/
LinkedList.prototype.append = function (element) {
var node = new Node(element), current;
if (this.head === null) {
this.head = node;
}
else {
current = this.head;
// 循环列表,知道找到最后一项
while (current.next) {
current = current.next;
}
// 找到最后一项,将其next赋为node,建立链接
current.next = node;
}
this.length++; // 更新列表长度
};
/**
* 向列表的特定位置插入一个新的项
* @param position
* @param element
*/
LinkedList.prototype.insert = function (position, element) {
// 检查越界值
if (position >= && position <= length) {
var node = new Node(element), current = this.head, previous = void , index = ;
if (position === ) {
node.next = current;
this.head = node;
}
else {
while (index++ < position) {
previous = current;
current = current.next;
}
node.next = current;
previous.next = node;
}
this.length++; // 更新列表长度
return true;
}
else {
return false;
}
};
/**
* 从列表的特定位置移除一项
* @param position
*/
LinkedList.prototype.removeAt = function (position) {
// 检查越界值
if (position > - && position < this.length) {
var current = this.head, previous = void , index = ;
// 移除第一项
if (position === ) {
this.head = current.next;
}
else {
while (index++ < position) {
previous = current;
current = current.next;
}
// 将previous与current的下一项链接起来:跳过current,从而移除它
previous.next = current.next;
}
this.length--;
return current.element;
}
else {
return null;
}
};
/**
* 从列表中移除一项
* @param element
*/
LinkedList.prototype.remove = function (element) {
var index = this.indexOf(element);
return this.removeAt(index);
};
/**
* :返回元素在列表中的索引。如果列表中没有该元素则返回-1
* @param element
*/
LinkedList.prototype.indexOf = function (element) {
var current = this.head, index = -;
while (current) {
if (element === current.element) {
return index;
}
index++;
current = current.next;
}
return -;
};
/**
* 如果链表中不包含任何元素, 返回true, 如果链表长度大于0则返回false
*/
LinkedList.prototype.isEmpty = function () {
return this.length === ;
};
/**
* 返回链表包含的元素个数。与数组的length属性类似
*/
LinkedList.prototype.size = function () {
return this.length;
};
/**
* 由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值
*/
LinkedList.prototype.toString = function () {
var current = this.head, string = '';
while (current) {
string += current.element;
current = current.next;
}
return string;
};
LinkedList.prototype.getHead = function () {
return this.head;
};
LinkedList.prototype.print = function () {
console.log(this.toString());
};
return LinkedList;
}());
JavaScript数据结构与算法(六) 链表的实现的更多相关文章
- JavaScript 数据结构与算法3(链表)
学习数据结构的 git 代码地址: https://gitee.com/zhangning187/js-data-structure-study 1.链表 本章学习如何实现和使用链表这种动态的数据结构 ...
- 为什么我要放弃javaScript数据结构与算法(第六章)—— 集合
前面已经学习了数组(列表).栈.队列和链表等顺序数据结构.这一章,我们要学习集合,这是一种不允许值重复的顺序数据结构. 本章可以学习到,如何添加和移除值,如何搜索值是否存在,也可以学习如何进行并集.交 ...
- 为什么我要放弃javaScript数据结构与算法(第五章)—— 链表
这一章你将会学会如何实现和使用链表这种动态的数据结构,这意味着我们可以从中任意添加或移除项,它会按需进行扩张. 本章内容 链表数据结构 向链表添加元素 从链表移除元素 使用 LinkedList 类 ...
- JavaScript数据结构与算法-链表练习
链表的实现 一. 单向链表 // Node类 function Node (element) { this.element = element; this.next = null; } // Link ...
- 重读《学习JavaScript数据结构与算法-第三版》- 第6章 链表(一)
定场诗 伤情最是晚凉天,憔悴厮人不堪言: 邀酒摧肠三杯醉.寻香惊梦五更寒. 钗头凤斜卿有泪,荼蘼花了我无缘: 小楼寂寞新雨月.也难如钩也难圆. 前言 本章为重读<学习JavaScript数据结构 ...
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- javascript数据结构与算法 零(前记+前言)
前记 这本书Data Structure and Algorithm with Javascript 我将其翻译成<< javascript 数据结构和算法>> 为什么这么翻译 ...
- 为什么我要放弃javaScript数据结构与算法(第九章)—— 图
本章中,将学习另外一种非线性数据结构--图.这是学习的最后一种数据结构,后面将学习排序和搜索算法. 第九章 图 图的相关术语 图是网络结构的抽象模型.图是一组由边连接的节点(或顶点).学习图是重要的, ...
- 为什么我要放弃javaScript数据结构与算法(第八章)—— 树
之前介绍了一些顺序数据结构,介绍的第一个非顺序数据结构是散列表.本章才会学习另一种非顺序数据结构--树,它对于存储需要快速寻找的数据非常有用. 本章内容 树的相关术语 创建树数据结构 树的遍历 添加和 ...
随机推荐
- 目前微服务/REST的最佳技术栈
服务端 日期 编程语言 Web Framework DbAccess/ORM 数据库 2017-09-07 Node.js 8.4 Koa 2.3 sequelize 4.8 MySQL 2017-0 ...
- SQL注入之Sqli-labs系列第二篇
废话不在多说 let's go! 继续挑战第二关(Error Based- String) 同样的前奏,就不截图了 ,and 1=1和and 1=2进行测试,出现报错 还原sql语句 查看源代码 ...
- 解决exlicpe以debug模式启动或运行速度非常慢的问题
该问题可能是由于eclipse和tomcat的交互而产生的, 在以debug模式启动tomcat时,发生了读取文件错误, eclipse自动设置了断点,导致tomcat不能正常启动. 解决方法如下:以 ...
- lua 二维数组创建
local arr= {} for i=1, 4 do arr[i] = {} end 使用时可以直接使用arr[i][j]
- Leaflet客户端学习笔记
Leaflet介绍 Leaflet 是一个为建设交互性好适用于移动设备地图,而开发的现代的.开源的 JavaScript 库.代码仅有 33 KB,但它具有开发在线地图的大部分功能.支持插件扩展, L ...
- 浅谈RMQ
RMQ是一类求区间极值的问题 有一种 \(O\left(nlogn\right)\) 的解法,用倍增实现 倍增算法 变量的定义 \(A_i\) : 原数组 \(f_{i,j}\) : 以 \(i\) ...
- 读论文系列:Object Detection CVPR2016 YOLO
CVPR2016: You Only Look Once:Unified, Real-Time Object Detection 转载请注明作者:梦里茶 YOLO,You Only Look Once ...
- 铜齿铁牙UP计划
铜齿铁牙UP计划 我在""做教练"之好声音训练"给出了老师.播音主持学习者,声乐学习者科学用声三要点: 用气发声 共鸣发声 虚实结合 用气发声首先要学会腹式呼吸 ...
- C++ STL常用容器基本用法汇总
1.vector 包含头文件#include<vector> 使用命名域using namespace std 定义元素类型为T的vector vector<T> vec 增: ...
- 第一篇:Python入门
一.编程与编程语言 编程的目的: 计算机的发明,是为了用机器取代/解放人力,而编程的目的则是将人类的思想流程按照某种能够被计算机识别表达方式传递给计算机,从而达到让计算机能够像人脑/电脑一样自动执行的 ...