什么是链表:链表中的元素在内存中并不是连续的,每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也可以称为指针)组成
链表被分为单向链表与双向链表;
单向链表中每一个元素只有一个next指针,用来指向下一节点,我们只能从链表的头部开始遍历整个链表,任何节点只能找到它的下一个节点,而不能找到它的上一个节点,
双向链表中的每一个元素拥有两个指针,一个用来指向下一个节点,一个用来指向上一个节点,双向链表中除了可以向单向链表一样从头部开始遍历外,还可以从尾部开始遍历;
在js这门语言中我们怎么表示链表呢,因为js中没有内置链表这种数据结构;所以我们需要创建一个类,这个类的作用就是描述链表的节点;
单向链表:
一个保存节点的值,一个保存指向下一个节点的指针;
function listNode(val){
this.val=val // 节点的值
this.next=null //指向下一个节点的指针;
}
//写一个链表类,其中length属性代表链表长度,head属性代表链表头部节点;
function LinkedList(){
this.length=0
this.head=null
}
这是向单向链表追加节点:分为两种情况,一种是链表中没有值时,一种是链表有值:
//向链表中追加节点;分为两种情况一种是链表中没有值时,一种是链表有值;
LinkedList.prototype.append=function(val){
let node=new listNode(val)
//链表为空时
if(!this.head){
this.head=node
}else{
let cur=this.getElementAt(this.length-1)
cur.next=node
//指针指向我新添加的节点;
}
//将链表长度加1;保证length属性等于链表长度;
this.length++
}
//获取链表中索引所对应的元素;
LinkedList.prototype.getElementAt = function (index) {
//判断参数index的边界值,如果值超出索引的范围(<0||>length-1)
if (index < 0 || index >= this.length) return null
let cur = this.head
while (index--) { //这里自减是因为链表的索引是从0开始的
cur = cur.next
}
return cur
}
通过节点值查找元素:
/find方法;通过节点值找元素
LinkedList.prototype.find = function (val) {
let cur = this.head
while (cur) {
if (cur.val == val) return cur
cur = cur.next
}
return null
}
使用链表:
let Linked = new LinkedList()
Linked.append(20);
Linked.append(17);
Linked.append(30);
console.log(Linked.join('--')); //20--17--30
双向链表:
创建一个双向链表:
创建链表节点类,不同的是,它需要多一个 prev 属性用来指向前一个节点
function listNodenod(val){
this.val=val
this.next=null
this.prev=null
}
//创建链表节点类,不同的是,它需要多一个 prev 属性用来指向前一个节点
function DoubleLinkedList(){
this.length=0
this.head=null
this.tail=null
}