当前位置: 首页 > Web前端 > JavaScript

数据结构——用JS实现链表——双向链表

时间:2023-03-27 01:39:49 JavaScript

前言数据结构——用JS实现链表——单链表上面简单介绍了下;本文作为续集出现。通过双向链表的实现,进一步加深了链表的一些概念和实现。编码部分由javascript实现。完整代码链接在链表末尾。双向链表也称为双向链表。它是一种链表。其中的每个数据节点都有两个指针,分别指向直接后继者和直接前驱者。因此,从双向链表中的任意一个节点开始,都可以方便地访问到它的前驱节点和后继节点。一般我们构造一个双向循环链表。【百度百科】链表的特点使用一组任意的内存空间来存储数据元素(这里的内存空间可以是连续的也可以是不连续的)。每个结点(node)都是由数据本身组成的,一个指向前一个结点,一个指向后一个结点的指针构成了整个链表的访问必须从头指针开始,而头指针指向第一个结点。尾指针结束,尾指针指向最后一个节点。JS中没有指针,上述节点的指针只是从C语言中借用的概念。链表复杂度时间复杂度AccessSearchInsertionDeletionO(n)O(n)O(1)O(1)空间复杂度O(n)基本操作实现节点结构//与单向链表的区别在于多了指向前面的指针节点类DoublyLinkedListNode{constructor(value,next=null,previous=null){this.value=value;这个.下一个=下一个;this.previous=上一个;}}链表初始化类DoublyLinkedList{constructor(){this.head=null;这。尾=空;//附加尾巴}}Addinsert(headandtail)//添加到headprepend(value){//添加节点到headconstnewNode=newDoublyLinkedListNode(value,this.head);//如果有头节点,则将其设置为头节点的前一个(previous)节点的引用//将头节点设置为新节点if(this.head){this.head.previous=newNode;}this.head=newNode;//如果没有尾节点,则将新节点设置为尾节点。如果(!this.tail){this.tail=newNode;}returnthis;}//添加到尾部append(value){constnewNode=newDoublyLinkedListNode(value);//同样判断如果没有头节点,则将新节点设置为头节点。//也是尾节点if(!this.head){this.head=newNode;this.tail=newNode;归还这个;}//如果有头节点(当然还有尾节点)//将头节点加入到链表的尾部this.tail.next=newNode;//想想转换,当前新节点上的每个节点(previous)都是当前指向的尾巴thisnewNode.previous=this.tail;//设置新节点This.tail=newNode;returnthis;}删除链表的末尾。为了阅读体验,这里省略了一些非关键代码,大家可以去仓库查看。稍后将发布链接。删除(值){如果(!this.head){返回空值;}让deletedNode=null;让currentNode=this.head;while(currentNode){if(currentNode.value===value){//仓库引入A比较js。逻辑很简单deletedNode=currentNode;//想一想,其实是处理了3种情况//1.删除的节点是头节点怎么办//2.如果删除的节点是尾节点,需要做什么Whattodo//3.如果不是头尾而是中间节点怎么办if(deletedNode===this.head){//如果删除的节点是头节点//那么设置head为第一个节点两个节点,thisnodewillbecomethenewhead//将head的previous设置为nullthis.head=deletedNode.next;如果(this.head){this.head.previous=null;}if(deletedNode===this.tail){this.tail=null;}}elseif(deletedNode===this.tail){//如果deleted是一个尾节点,设置tail为倒数第二个节点,它将成为新的尾节点this.tail=deletedNode.previous;this.tail.next=null;}else{//如果要删除中间节点constpreviousNode=deletedNode.previous;constnextNode=deletedNode.next;previousNode.next=nextNode;下一个节点.上一个=前一个节点;}}currentNode=currentNode.next;}returndeletedNode;}遍历链表编码实现部分体现在删除,可以自己抽取//思路很简单就是比较值while(){//转发遍历,如果没有当前顺序,则查找下一个直到结束//反之,如果没有之前的顺序,直到头部。}结论简单总结一下,双向链表结构简单理解就是一个结点包含当前值,前一个previous,下一个next。然后初始化就是head和tail。然后在这个基本结构上进行增删改查。慢慢理解后,会觉得很简单。最后,不要忘记在实际场景中多做一些连接。上述示例代码存储库的其他链接