JavaScript 实现双向链表的操作
Posted YuLong~W
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 实现双向链表的操作相关的知识,希望对你有一定的参考价值。
JavaScript实现双向链表 :使用ES6面向对象语法
双向链表: 每个结点都有一个指向其前一个结点的指针域(prev)和一个指向其下一个结点的指针域(next)
与单链表区别:
单链表是单向的,有一个头结点,一个尾结点,要访问任何结点,都必须知道头结点,不能逆着进行
双向链表基于单链表。双链表添加了一个指针域,通过两个指针域,分别指向结点的前结点和后结点。可以通过双链表的任何结点,访问到它的前结点和后结点
链表的设计:
一个是 Node 类用来表示结点,另一个是 DoubleLinked 类提供插入结点、删除结点、遍历结点等一些操作
在链表中间的某个结点前插入:
给定p结点,要求在p结点前插入s结点
注意四步操作的顺序:
- ① s.prev=p.prev
- ② p.prev.next=s(也可写作s.prev.next=s 前提是先执行①,否则不可)
- ③ s.next=p
- ④ p.prev=s
注意: 以上四步顺序中,④一定要放在①后,因为一旦添加④,p结点的pre已经确定指向s结点,如果没有①,则p结点的前一个结点将会丢失,无法找到,而其余顺序随意排放
建议按照以上①②③④顺序进行排列,思路很清晰脑子不会乱
在链表中删除某个结点:
删除给定的p结点
顺序:
- ① p.prev.next=p.next
- ② p.next.prev=p.prev
注意: ① ②顺序无所谓,谁先谁后都可
双链表代码:
//定义一个节点类
class Node {
constructor(data) {
this.data = data
this.next = null
this.previous = null
}
}
//双向链表类
class DoubleLinked {
constructor() {
this.size = 0
this.head = new Node('head')
this.currentNode = '' //当前节点指针
}
//获取链表长度
getLength() {
return this.size
}
//判断链表是否为空
isEmpty() {
return this.size === 0
}
//显示当前节点
showNode() {
console.log(this.currentNode.data)
}
//遍历
displayList() {
let str = ''
let currentNode = this.head //打印结果带head值
// var currentNode=this.head.next 打印结果不带head值
while (currentNode) {
str += currentNode.data
currentNode = currentNode.next
if (currentNode) {
str += '-->'
}
}
console.log(str)
}
//倒序遍历链表
lastDisplay() {
let str = ''
let currentNode = this.findLast()
while (currentNode) {
str += currentNode.data
currentNode = currentNode.previous
if (currentNode) {
str += '-->'
}
}
console.log(str)
}
//查找某一个元素
findNode(data) {
let currentNode = this.head
while (currentNode && (currentNode.data != data)) {
currentNode = currentNode.next
}
return currentNode
}
//头插法 在headh结点后添加结点(与insertNextNode()方法类似)
headAppend(data) {
let newNode = new Node(data)
newNode.next = this.head.next
this.head.next.previous = newNode
newNode.previous = this.head
this.head.next = newNode
this.size++
}
//获取最后一个节点
findLast() {
let currentNode = this.head
while (currentNode.next) {
currentNode = currentNode.next
}
return currentNode
}
//尾插法 在尾部添加节点
append(data) {
let currentNode = this.findLast()
let newNode = new Node(data)
currentNode.next = newNode
newNode.next = null
newNode.previous = currentNode
this.size++
}
//插入节点 表示将element值插入到data值之后
insertNextNode(data, element) {
let currentNode = this.findNode(data)
//如果data不存在
if (!currentNode) {
return
}
let newNode = new Node(element)
newNode.next = currentNode.next
currentNode.next.previous = newNode
// newNode.next.previous=newNode
newNode.previous = currentNode
currentNode.next = newNode
this.size++
}
//插入节点 表示将element值插入到data值之前
insertPreNode(data, element) {
let currentNode = this.findNode(data)
if (!currentNode) {
return
}
let newNode = new Node(element)
newNode.previous = currentNode.previous
currentNode.previous.next = newNode
// newNode.previous.next=newNode
newNode.next = currentNode
currentNode.previous = newNode
this.size++
}
//删除一个节点
deleteNode(data) {
let currentNode = this.findNode(data)
if (currentNode.next == null) //如果删除的节点是最后一个节点
{
currentNode.previous.next = null
}
else {
currentNode.previous.next = currentNode.next
currentNode.next.previous = currentNode.previous
}
this.size--
}
}
代码检测:
//创建一个空链表
let doubleList = new DoubleLinked()
//判断是否为空
console.log(doubleList.isEmpty())
//尾插法依次插入数组序列
let arr = [1, 3, 5]
for (let i = 0; i < arr.length; i++) {
doubleList.append(arr[i])
}
//遍历双向链表
doubleList.displayList()
//指定结点后插入新结点
doubleList.insertNextNode(3, 4)
//指定结点前插入结点
doubleList.insertPreNode(3, 2)
doubleList.displayList()
//删除指定结点
doubleList.deleteNode(5)
doubleList.displayList()
//前插法 在头元素后插入结点
doubleList.headAppend(20)
doubleList.headAppend(100)
doubleList.displayList()
//倒序遍历
doubleList.lastDisplay()
以上是关于JavaScript 实现双向链表的操作的主要内容,如果未能解决你的问题,请参考以下文章