什么是链表
数组(或者也可以称作列表)是一种非常简单的存储结构。在这一章中,你会学习如何使用链表这种动态的结构。这意味着我们可以从中任意添加或者移除项。它会按需进行扩容。
要存储多个元素。数组(或列表)可能是最常用的数据结构,正如之前所提到过的。每种语言都实现了数组。这种结构非常方便。提供了一个便利的【】语法来操作它的元素。然而,这种数据结构有一个缺点:(在大多数语言中)数组的大小是固定的。从数组的起点或者中间插入或者移除项的成本很高。因为需要移动元素(尽管我们已经学过过的JavaScript的Array类方法可以帮助我们做这些事。但是背后的情况是这样)。
链表存储有序的元素集合。但不同于数组。链表的元素在内存中并不是连续存放的。每个元素由一个存储节点本身的元素和指向下一个元素的指针。的引用。也称指针和链接组成。下图展示了一个链表的结构:
相对于使用传统数组,链表还有一个好处在于,添加或者移除元素的时候不需要移动其他元素。然而,链表需要使用指针。因此实现链表时需要格外注意。数组的另外一个细节是可以直接访问道任意位置的元素。而想要访问链表任意一个位置的元素,我们需要从起点开始迭代链表直到找到所需的元素。需要从起点(表头开始迭代链表)直到找到需要的元素。
创建一个链表
理解了什么是链表之后,我们就要开始实现我们的数据结构了。以下是LinkedList类的骨架:
// 这里是链表function LinkedList(){ // 头结点 let head=null // 定义长度 let length=0 // 往头部插入一个元素 this.append=function(element){ } // 在链表的指定位置插入一个元素 this.insert=function(position){ } // 更具下标移除链表指定为止的元素 this.removeAt=function(position){ } // 根据元素内容移除链表指定位置的元素 this.remove=function(element){ } // 更具下标获取链表指定位置的元素 this.indexOf=function(position){ } // 判断链表是否为空 this.isEmpty=function(){ } // 获取链表的长度 this.size=function(){ } // 打印链表 this.toString=function(){ }}// 这里是存储链表元素的结点类class Node{ constructor(element){ this.element=element this.next=null }}function fn(){ let list=new LinkedList()}fn()
链表的API文档:
- append:往头部插入一个元素
- insert:在链表的指定位置插入一个元素
- removeAt:更具下标移除链表指定为止的元素
- remove:根据元素内容移除链表指定位置的元素
- indexOf:更具下标获取链表指定位置的元素
- isEmpty:判断链表是否为空
- size:获取链表的长度
-
toString:打印链表
具体实现
function LinkedList(){ let head=null; let length=0; this.append=function(element){ let node=new Node(element) let current=null if(head==null){ head=node }else{ current=head; while(current.next){ current=head.next } current.next=node; } length++ } this.insert=function(position,element){ if(position>=0&&position<=length){ let node=new Node(element) let current=head; let previous=null let index=0; if(position===0){ node.next=current; head=node }else{ while(index++<position){ previous=current; current=current.next } node.next=current previous.next=node; } length++ return true }else{ return false } } this.removeAt=function(position){ if(position>-1&&position<length){ let current=head let previous=null let index=0; if(position===0){ head=current.next }else{ while(index++<position){ previous=current current=current.next } previous.next=current.next } length--; return current.element; }else{ return null } } this.remove=function(element){ let index=this.indexOf(element); return this.removeAt(index) } this.indexOf=function (position){ let current=head; let index=-1; while(current){ if(element===current.element){ return index } index++; current=current.next; } return -1 } this.isEmpty=function(){ return length===0 } this.size=function(){ return length } this.toString=function(){ let current=head; let s='' while(current){ s+=current.element+" " current=current.next } return s; }}class Node{ constructor(element){ this.element=element; this.next=null this.length=0; this.head=null }}function fn(){ let list=new LinkedList() list.append(15) list.append(10) console.log(list.toString())}fn()