//创建一个节点,每个节点具有两个属性,一个是值和一个指针
class Node {
constructor(value) {
this.value = value
this.next = null
}
}
//创建一个链表,包含三个属性
class LinkedList {
constructor() {
this.head = null
this.tail = this.head //用于存储链表的最后一个节点tail
this.length = 0 //用于保存链表长度
}
//按顺序添加值,将一个节点添加到链表的末尾
append(value) {
const newNode = new Node(value)
//检查链表是否为空
if(!this.head) {//链表为null,将新的节点分别赋给head和tail
//此时head指向null,因此我们创建一个新对象,并将对象分配给head和tail
this.head = newNode
this.tail = newNode
//现在head和tail都指向一个对象
} else {//链表不为空,将新的节点追加到链表的尾部
//现在head不指向null,所以我们进入append函数的else的分支
this.tail.next = newNode//由于head和tail都指向同一个对象,tail的变化都会导致head对象的变化,这是JS中对象的工作方式,在js中,对象都是通过引用传递的,因此head和tail都指向存储对象的相同地址空间
//上面这行代码相当于 this.head.next = node
this.tail = newNode
//执行完上面的代码行之后,this.head.next和this.tail指向同一个对象,因此当我们添加新节点的时候,head对象都会自动更新
}
this.length++
}
// //append()函数
// const linkedList1 = new LinkedList()
// linkedList1.append(2)
// linkedList1.append(3)
// linkedList1.append(4)
// // //执行完三次append之后,linkedList1的结构
// // // head: {value: 2 , next: {value: 3, next: {value: 4,next: null}}}
// // // tail : {value: 4, next: null}
// // // length:3
//prepend(将值添加到链表开头)
prepend(value) {
const node = new Node(value)
node.next = this.head//将新结点的next指向head
this.head = node//头结点变为node
this.length++
}
getPrevNextNodes(index) {//这个函数可以返回prevNode和nextNode的值,用于下面的insert()函数
let count = 0
let prevNode = this.head
let nextNode = prevNode.next
while(count < index - 1) {
prevNode = prevNode.next
nextNode = prevNode.next
count++
}
return {
prevNode,
nextNode
}
}
//在特定索引处添加值
insert(value,index) {
if(index >= this.length) {//若是index的值大于或者等于length属性,则将操作移交给append函数
this.append(value)//在最后面添加值
}
const node = new Node(value)
const {prevNode,nextNode} = this.getPrevNextNodes(index)//这块我所借鉴的博客写的是 thisg.getPrevNextNodes(index),不知是否正确
prevNode.next = node//将prevNode的next属性指向新节点
node.next = nextNode//将新节点的next属性指向nextNode
this.length++
}
getNode(index) {//这个函数可以返回prevNode和currentNode的值,用于下面的remove()函数
let count = 0
let prevNode = this.head
let currentNode = prevNode.next
while(count < index - 1) {
prevNode = prevNode.next
currentNode = prevNode.next
}
return {
prevNode,
currentNode
}
}
//删除特定索引处的元素
remove(index){
let {prevNode,crrentNode} = this.getNode(index)
prevNode.next = crrentNode.next
this.length--
}
//反转链表
reverse() {
let previousNode = null
let currentNode = this.head
while(currentNode !== null) {
let nextNode = currentNode.next//将nextNode分配给currentNode.next
currentNode.next = previousNode//将currentNode.next属性指向previousNode
previousNode = currentNode//将previousNode移动至currentNode
currentNode = nextNode//将currentNode移动至nextNode
}
this.head = previousNode//最后将previousNode值分配给head
}
//查找
lookup(index) {
let counter = 0
let currentNode = this.head
while(counter < index) {
currentNode = currentNode.next
counter++
}
return currentNode
}
}
JS关于单链表的基本操作
最新推荐文章于 2024-01-12 07:15:00 发布