本篇主要有三部分

  • 什么是链表
  • 链表的实现
  • 链表的变种

源码地址:github.com/yhtx1997/Sm…

另外,今天2019年2月18日上午发现 2048-vue 版,代码版本不对,且最新版本遗失,无奈只得重新修复了下
2048-vue地址: github.com/yhtx1997/Sm…

什么是链表

链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个 元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。
相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然 而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何 位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到 所需的元素。
如下图:

注:其中 00 06 10 12 18 为假定在内存中的地址

我将已经做好的链表存入数据,然后在控制台打印出来是这样的:

它看起来就像是这样的,一层套一层

其实应该是下面这样,类似于栓狗的铁链

链表的实现

链表功能

  • 添加元素
  • 获取指定位置元素
  • 在指定位置插入元素
  • 移除指定位置的元素
  • 返回指定元素的位置
  • 移除指定元素
  • 是否为空
  • 长度
  • 获取表头
  • 清空链表
  • 转换为字符串输出
// 链表元素
class Node {constructor(element) {this.element = element; // 元素this.next = undefined; // 指向下一个元素}
}
class LinkedList {// 构造函数声明一些全局变量constructor(){this.count = 0; // 长度this.head = undefined; // 第一个元素}// 添加元素push(element) {}// 获取指定位置元素getElementAt(index) {}// 在指定位置插入元素insert(element, index) {}// 移除指定位置的元素removeAt(index) {}// 返回指定元素的位置indexOf(element) {}// 移除指定元素remove(element) {}// 是否为空isEmpty() {}// 长度size() {}// 获取表头getHead() {}// 清空链表clear() {}// 转换为字符串输出toString() {}
}
复制代码

代码实现

class LinkedList {// 构造函数声明一些全局变量constructor(){this.count = 0; // 长度this.head = undefined; // 第一个元素}// 添加元素push(element) {const node = new Node(element);if (this.head === undefined) {this.head = node;} else {let current = this.head;while (current.next !== undefined) {current = current.next;}current.next = node;}this.count++;}// 获取指定位置元素getElementAt(index) {// 判断不是空链表if (this.isEmpty() || index > this.count || index < 0) { // 非空才能继续处理// 判断不大于最大长度,不小于最小长度(0)return undefined;}// 循环找到元素let current = this.head;for (let i = 0; i < index; i++){current = current.next;}return current;// 返回找到的元素}// 在指定位置插入元素insert(element, index) {// 创建一个元素let current = new Node(element);// 首先确定是不是在首位置插入if (index === 0){current.next = this.head;this.head = current;} else {// 找到指定位置前一个元素let previous = this.getElementAt(index - 1);// 将前一个元素的 next 赋值给插入元素的 nextcurrent.next = previous.next;// 将插入元素的 node 赋值给前一个元素的 nextprevious.next = current;}this.count++;}// 移除指定位置的元素removeAt(index) {let current = this.head;if (index === 0){this.head = current.next;} else {// 找到这个元素和这个元素之前的元素let previous = this.getElementAt(index - 1);current = previous.next;// 将这个元素的 next 赋值给这个元素之前元素的 nextprevious.next = current.next;}this.count--;// 返回要移除的元素return current.element;}// 返回指定元素的位置indexOf(element) {// 从头开始找let current = this.head;// 不超过最大长度for (let i = 0; i < this.size() && current != null; i++){if (current.element === element){ // 找到相等的就返回下标return i;}current = current.next;}return -1;}// 移除指定元素remove(element) {// 获取指定元素位置let index = this.indexOf(element);// 移除指定位置元素return this.removeAt(index);}// 是否为空isEmpty() {return this.size() === 0;}// 长度size() {return this.count;}// 获取表头getHead() {return this.head;}// 清空链表clear() {this.head = undefined;this.count = 0;}// 转换为字符串输出toString() {if (this.head == null) {return '';}let objString = `${this.head.element}`;let current = this.head.next;for (let i = 1; i < this.size() && current != null; i++) {objString = `${objString},${current.element}`;current = current.next;}return objString;}
}
let a = new LinkedList();
a.push('a');
a.push('b');
a.push('c');
a.push('d');
a.push('e');
a.push('f');
a.push('h');
a.push('i');
a.push('j');
a.push('k');
a.push('l');
a.push('m');
a.push('n');
a.push('o');
a.push('p');
a.push('q');
a.remove('a');
a.insert('a',1);
console.log(a);
复制代码

插入元素图解:

现在有狗链两节,我要在中间加一节

先把两节分开,

然后把前边的尾部与要加的头部相连,然后把要加的尾部与后边的头部相连

0 连 xx , xx 连 1

链表的变种

双向链表

我们已经知道链表的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成,双向链表除了这个基本特性,每个元素还包含一个指向前一个元素的引用,如图所示:

循环链表

循环链表就是链表的最后一个指向下一个元素的引用指向了第一个元素,使其成为循环链表

双向循环链表

双向循环链表就是双向链表的第一个元素指向前一个的引用指向了最后一个元素,而最后一个元素指向下一个元素的引用指向了第一个元素,如图所示:

[ JavaScript ] 数据结构与算法 —— 链表相关推荐

  1. JavaScript数据结构与算法——链表详解(下)

    在JavaScript数据结构与算法--链表详解(上)中,我们探讨了一下链表的定义.实现原理以及单链表的实现.接下来我们进一步了解一下链表的其他内容. 1.双向链表 双向链表实现原理图: 与单向链表不 ...

  2. JavaScript数据结构与算法——链表详解(上)

    注:与之前JavaScript数据结构与算法系列博客不同的是,从这篇开始,此系列博客采用es6语法编写,这样在学数据结构的同时还能对ECMAScript6有进一步的认识,如需先了解es6语法请浏览ht ...

  3. JavaScript数据结构与算法(1)(数组、栈、队列、链表)(ES6)

    注意:原教学视频:JavaScript(ES6)数据结构和算法 | JavaScript数据结构与算法 (都是CoderWhy老师的教学) 原作者(笔记)链接:JavaScript 数据结构与算法 | ...

  4. 重读《学习JavaScript数据结构与算法-第三版》- 第6章 链表(一)

    定场诗 伤情最是晚凉天,憔悴厮人不堪言: 邀酒摧肠三杯醉.寻香惊梦五更寒. 钗头凤斜卿有泪,荼蘼花了我无缘: 小楼寂寞新雨月.也难如钩也难圆. 前言 本章为重读<学习JavaScript数据结构 ...

  5. 学习JavaScript数据结构与算法(一):栈与队列

    本系列的第一篇文章: 学习JavaScript数据结构与算法(一),栈与队列 第二篇文章:学习JavaScript数据结构与算法(二):链表 第三篇文章:学习JavaScript数据结构与算法(三): ...

  6. JavaScript数据结构和算法简述——数组

    为什么先讲数组 数据结构可以简单的被分为线性结构和非线性结构. 线性结构大致包括: 数组(连续存储): 链表(离散存储): 栈(线性结构常见应用,由链表或数组增删和改进功能实现): 队列(线性结构常见 ...

  7. JavaScript数据结构和算法简述——前言

    为什么要使用数据结构和算法(程序=数据结构+算法)         数据结构是对在计算机内存中(有时在磁盘中)的数据的一种安排.包括数组.链表.栈.二叉树.哈希表等.        算法是对这些结构中 ...

  8. 学习JavaScript 数据结构与算法

    学习链接:https://github.com/XPoet/js-data-structures-and-algorithms JavaScript 数据结构与算法 1.数据结构(data struc ...

  9. JavaScript数据结构与算法(2)(集合、字典、哈希表、二叉树、图)(ES6)

    注意:原教学视频:JavaScript(ES6)数据结构和算法 | JavaScript数据结构与算法 (都是CoderWhy老师的教学) 原作者(笔记)链接:JavaScript 数据结构与算法 | ...

最新文章

  1. lazyload.js详解
  2. Lua语言学习-垃圾回收
  3. android jpush json,发送了正确的JPush json却报1002
  4. 谷歌大脑推出视觉领域任务自适应基准:VTAB
  5. HDU-1863-畅通工程(并查集)
  6. lvds输入悬空_LVDS的接口电路设计
  7. 【电信学】【2019.07】基于ATOLL的5G网络规划与优化
  8. java assert 断言_Java 之 assert (断言)
  9. 人力资源管理专业知识与实务(初级)【6】
  10. 408真题-解析-2014年计算机考研真题解析
  11. 美国网站直接shopping之经验总结
  12. Matplotlib从入门到精通05-样式色彩秀芳华
  13. 海藻酸盐壳聚糖水凝胶微球载体/PLGA/nHA支架复合rhBMP-2壳聚糖纳米微球水凝胶的制备
  14. hdu 5238 Calculator(线段树+CRT)
  15. 计算机应用中dss是,在计算机应用中,英文缩写“DSS”表示( )。
  16. [应用相关]NUCLEO-H7A3ZI-Q板子学习
  17. Linux升级gcc到最新版本--gcc-9.1.0
  18. 构建数字经济新生态,和数区块链结合隐私计算可发挥作用
  19. MATLAB | 世界杯来用MATLAB画个足球玩叭~
  20. The rate shock 利率冲击 | 经济学人中英双语精读笔记

热门文章

  1. boost::histogram::accumulators::mean用法的测试程序
  2. boost::hof::flip用法的测试程序
  3. boost::hana::front用法的测试程序
  4. boost::graph模块实现bellman算法的测试程序
  5. boost::function_types::is_function用法的测试程序
  6. 宏BOOST_TEST_ALL_WITH的用法实例
  7. Boost:自定义小矢量的测试程序
  8. Boost:是否支持sse2指令的测试程序
  9. Boost:align overflow对齐溢出的测试程序
  10. ITK:从均匀矩阵应用仿射变换并重新采样