欢迎和号主【前端点线面】进群盘算法,此外本号干货满满:14个门类(100+篇原创)内容(又干又硬)《前端百题斩》pdf(助力薪资double)20+篇思维导图(知识系统化、记忆简单化),进摸鱼群

一、基础

一、定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

二、相关概念

一个完整的链表需要由以下几个部分组成:

  1. 头指针:一个普通的指针,它的特点是永远指向链表第一个结点的位置;

  2. 结点:节点包含三类:头结点、首元节点和其它节点。

(1)头结点(非必须):一个不存任何数据的空节点,通常作为链表的第一个节点;

(2)首元结点:链表中第一个存有数据的节点称为首元结点;

(3)其它结点:链表中的其它结点

image-20220328203505736.png

三、结点包含内容

链表中每个节点包含两个部分:

  1. 数据域:存储数据元素本身;

  2. 指针域:指向直接后续元素的指针

image-20220328200136679.png

二、链表分类及相关操作

链表存在很多种类,下面重点讲述单向链表、双向链表的结点结构,以及其对应的CURD(添加、更改、查找、删除)。

2.1 单向链表

对于单链表的相应编程,我们均按照默认头指针指向首元结点这样的结构进行代码实现。

一、结点结构

结点作为链表的重要组成部分,其结构可用如下代码表示:

function ListNode(val, next) {this.val = val;this.next = next === undefined ? null : next;
}

扩展:如何根据一个数组创建链表

function createLinkedList(arr) {const head = new ListNode(arr[0]);let current = head;for (let i = 1; i < arr.length; i++) {const node = new ListNode(arr[i]);current.next = node;current = current.next;}return head;
}

二、遍历(查找)

在链表中查找指定数据元素,其思路是从表头依次遍历表中节点,用被查找元素与各结点中存储的数据元素进行对比,直到对比成功或遍历至链表最末端的null。

// 查找
function selectVal(head, val) {let current = head;// 判断是否为nullwhile (current) {// 判断是否对比成功if (current.val === val) {return current;}current = current.next;}return null;
}

三、添加

向链表中添加元素,根据添加位置不同,可分为3中情况:

  1. 插入到链表的头部

  2. 插入到链表中间的某个位置

  3. 插入到链表的最末端,作为链表中最后一个数据元素

插入思想

  1. 将新结点的next指针指向插入位置后的结点

  2. 将插入位置前结点的next指针指向插入结点

function insertVal(head, val, add) {const newNode = new ListNode(add);// 查找插入节点const currentNode = selectVal(head, val);if (!currentNode) {return null;}// 1. 将新结点的next指针指向插入位置后的节点newNode.next = currentNode.next;// 2. 将插入位置前节点的next指针指向插入节点currentNode.next = newNode;return head;
}

四、删除

删除的元素的时候要注意链表的结构,注意有没有空值的头结点,有头结点的时候删除的时候就不需要判断删除的是不是第一个值,否则需要进行判断

function delVal(head, val) {// 当一个结点也不存在时,直接返回空if (!head) {return null;}// 如果删除的是第一个节点,直接将head指向第二个节点if (head.val === val) {head = head.next;return head;}// 如果删除的不是第一个节点let current = head;// 找到待删除元素的前一个值while (current.next && current.next.val !== val) {current = current.next;}if (current.next) {// 将删除结点的前一个结点的next值直接指向删除结点的下一个节点current.next = current.next.next;}return head;
}

五、更改

更新链表中的元素,只需要通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可。

function updateVal(head, val, newVal) {let current = head;while (current) {if (current.val === val) {current.val = newVal;return head;}current = current.next;}return null;
}

2.2 双向链表

单链表只有一个方向,从头结点到尾结点,双向链表指各个节点之间的逻辑关系是双向的,其结点结构和链表结构如下所示:

  1. 结点结构

image-20220330194222686.png
  1. 链表结构

image-20220330193934911.png

一、结点结构

双向链表的节点结构相比于单向链表,多了一个prev属性,如下所示:

function ListNode(val, prev, next) {this.val = val;this.prev = prev === undefined ? null : prev;this.next = next === undefined ? null : next;
}

二、遍历(查找)

双向链表的查找和单向链表的查找类似,都是遍历链表。

function selectVal(head, val) {let current = head;while (current) {if (current.val === val) {return current;}current = current.next;}return null;
}

三、添加

在某个节点后插入结点,其思想是:

  1. 找到该插入结点;

  2. 将新结点的next指针指向插入位置后的结点;

  3. 将新结点的prev指针指向插入位置的结点;

  4. 将插入节点的next指针指向新结点

/*** 插入(在某个节点后插入)*/
function insertVal(head, val, add) {const newNode = new ListNode(add);// 查找插入节点const currentNode = selectVal(head, val);if (!currentNode) {return null;}// 1. 将新结点的next指针指向插入位置后的结点newNode.next = currentNode.next;// 2. 将新结点的prev指针指向插入位置的结点newNode.prev = currentNode;// 3. 将插入节点的next指针指向新结点currentNode.next = newNode;return head;
}

四、删除

双链表删除结点时,只需要遍历链表找到要删除的链表,然后将该链表从表中摘除即可。

(注:针对头指针直线的结点需要做特殊处理,否则head永远指向的是原始的第一个节点)

/*** 删除* * 双链表删除结点时,只需要遍历链表找到要删除的链表,然后将该链表从表中摘除即可*/
function delVal(head, val) {let current = head;while (current) {if (current.val === val) {if (current.next) {current.next.prev = current.prev;}if (current.prev) {current.prev.next = current.next;} else {// 针对头指针直线的结点需要做特殊处理,否则head永远指向的是原始的第一个节点head = current.next;}return head;}current = current.next;}return null;
}

五、更改

更新链表中的元素,只需要通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可。

/*** 更新* * 更新链表中的元素,只需要通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可*/
function updateVal(head, val, newVal) {let current = head;while (current) {if (current.val === val) {current.val = newVal;return head;}current = current.next;}return null;
}

··············· 执鸢者简介 ·················

看号主详细信息,来这

瞅一瞅

畅所欲言交流

【1】前端百题斩系列

【2】Vue系列

【3】React系列

【4】前端基础系列

【5】基础知识

【6】浏览器系列

【7】构建工具系列

【8】网络系列

【9】Node系列

【10】源码系列

【11】前端有意思

【12】手撕算法系列

【13】个人总结

【14】杂科

美女面试官问我链表的CURD,我彻底懵圈了……相关推荐

  1. java代码编译之后是如何运行的?不知道这些,面试官问你jvm问题,你只能懵圈

    目录 从机器语言->汇编语言->高级语言 JVM的整体结构 java代码执行流程 java虚拟机种类(常用的就是HotSpot) 从机器语言->汇编语言->高级语言 计算机系统 ...

  2. 美女面试官问我Python如何优雅的创建临时文件,我的回答....

    [摘要] 本故事纯属虚构,如有巧合,他们故事里的美女面试官也肯定没有我的美,请自行脑补... 小P像多数Python自学者一样,苦心钻研小半年,一朝出师投简历. 这不,一家招聘初级Python开发工程 ...

  3. 美女面试官问我:能说几个常见的Linux性能调优命令吗?

    案例关注"Java后端技术全栈" 回复"000"获取大量电子书 本文主要内容: 简单回答: top.iostat.pidstat.ps.vmstat.netst ...

  4. 面试官问我 “A + B” 算法,我懵了

  5. 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮

    前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的 ...

  6. 字节跳动面试官问我看过哪些源码,然后就没有然后了

    最近,我的一位朋友在找工作,已经拿到了美团.快手等公司的Offer,准备选择其中一家入职了. 后来他又接到了字节跳动的电话,通知他去参加三面.从二面到三面之间隔了挺久的,他以为都没戏了,结果就收到了通 ...

  7. 面试官问你B树和B 树,就把这篇文章丢给他

    原文链接:面试官问你B树和B 树,就把这篇文章丢给他 在看这篇文章之前,我们回顾一下前面的几篇关于MySQL的文章,应该对你读下面的文章有所帮助. InnoDB与MyISAM等存储引擎对比 面试官问你 ...

  8. 面试官问我:Redis 内存满了怎么办

    转载自 想不到!面试官问我:Redis 内存满了怎么办 Redis占用内存大小 Redis的内存淘汰 LRU算法 LRU在Redis中的实现 LFU算法 问题 Redis占用内存大小 我们知道Redi ...

  9. 面试官问面向对象特点_最好的面试官有什么共同点?

    面试官问面向对象特点 by Aline Lerner 通过艾琳·勒纳(Aline Lerner) 最好的面试官有什么共同点? 我们查看了成千上万的真实访谈以找出答案. (What do the bes ...

最新文章

  1. python课程推荐-推荐几个优质的 Python 学习资料(良心推荐,非广告)
  2. KindEditor 在线编辑器
  3. Android 获取存储卡路径和空间使用情况
  4. CV之IS:利用pixellib库基于mask_rcnn_coco模型对《庆余年》片段实现实例分割简单代码全实现
  5. boost::hana::replicate用法的测试程序
  6. laravel php resources,利用 Laravel Resources 来整合第三方 API 数据
  7. ai边缘平滑_AI基础教程113:“效果”菜单之“画笔描边”(一)喷溅效果
  8. 探索Windows命令行系列(7):通过命令编译C#类和Java类
  9. set,env,export,set -x,set -e;
  10. 红盟云卡-开源的发卡网源码
  11. perform指标分析_Perform+3D-入门实战指导.ppt
  12. office各种格式文件对应的MIME Type/http:Content-Type
  13. python国内外研究现状-对当今Python 快速发展的研究与展望
  14. 西门子plc与oracle报文,西门子PLC以太网 通讯协议 解析
  15. 计算机专业考研集成电路,准备考研,“控制科学与工程”与“集成电路”,该怎么选?...
  16. MFC如何调用Flash控件
  17. 通用贷款计算器js 计算方法
  18. Activiti实现会签功能程序Demo
  19. c语言参悟之旅,Activity生命周期管理之三——S...-《C语言参悟之旅》-读书笔记...-C++函数参数小结_169IT.COM...
  20. linux 设备文件动态,使用 udev 高效、动态地管理 Linux 设备文件

热门文章

  1. 【路径规划】局部路径规划算法——贝塞尔曲线法(含python实现 | c++实现)
  2. Python老司机手把手带你写爬虫,整站下载妹子图,一次爽个够!
  3. 室内设计CAD怎么样?CAD适合什么人群学?
  4. 数据结构第十二天——普利姆算法和迪杰斯特拉算法
  5. nui-app vue.js项目实战---微信小程序
  6. 人工智能如何改变我们的未来生活
  7. 团队软件库_当地的财务管理软件网络推广哪家比较好
  8. 协同管理软件方面的一些文章
  9. 如何转换音频数据格式1
  10. 过河游戏(算法详解+例题)