单项链表的基本使用
单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点.
听起来很复杂,直接上图就很好理解了:
最近在算法题上看到链表就很好奇,毕竟我只听说其他的编程语言上有链表但不知道js怎么去实现,然后通过自己的摸索在大致了解一些,基本是实现了链表。下面是我实现链表的代码:
// 定义节点类
class Node {
constructor(el) {
this.el = el
this.next = null
}
}
// 定义链表类
class LinkedList {
constructor() {
this.size = 0
this.head = null
}
// 末尾添加node
append(el) {
let node = new Node(el)
// 如果链表为空则直接将节点赋值给head
if (this.size === 0) {
this.head = node
this.size++
} else {
// 链表不为空将添加带最后一个节点的后面
let currentNode = this.head
while (currentNode.next !== null) {
currentNode = currentNode.next
}
currentNode.next = node
this.size++
}
}
// 根据索引获取node
get(index) {
// 如果索引超出范围或着不是数字就会抛出错误
if ((index < 0) | (index >= this.size) | (typeof index !== 'number')) {
throw Error('out range or index is not number!')
}
// 索引为0 取head的el
if (index == 0) return this.head
// 索引不为零 如果取索引为2的就需要调用2次next
let currentNode = this.head
while (index) {
currentNode = currentNode.next
index--
}
return currentNode
}
// 向目标节点的后面添加
insertAfter(el, target) {
let currentNode = this.head
// 要插入的节点
const node = new Node(el)
// 目标节点
const targetNode = this.getNode(target)
// 目标节点的next
const targetNodeNext = targetNode.next
// 要插入的节点的next 为目标节点的next
node.next = targetNodeNext
// 便利链表 不是目标节点继续next
while (currentNode !== null && currentNode !== targetNode) {
currentNode = currentNode.next
}
// 在此处currentNode是目标节点
// 把新的节点覆盖目标节点的next上
currentNode.next = node
this.size++
}
// 删除指定节点
remove(el) {
let currentNode = this.head
const removeNode = this.getNode(el)
const removeNodeNext = removeNode.next
// 如果删除的是第一个节点
if (currentNode.el == el) {
this.head = null
this.size = 0
return
}
// 获取删除节点的前一个节点
while (currentNode !== null) {
// 如果当前节点的next时要删除的节点
if (currentNode.next == removeNode) {
// 将要删除节点的next接赋值给当前节点的next
currentNode.next = removeNodeNext
this.size--
break
}
currentNode = currentNode.next
}
}
// 清空链表
clear() {
this.head = null
this.size = 0
}
// 获取指定node
getNode(el) {
let currentNode = this.head
while (currentNode !== null && currentNode.el !== el) {
currentNode = currentNode.next
}
return currentNode
}
}
效果图:
向末尾添加节点
查找节点
在指定节点之后插入新的节点
删除指定节点
清空链表