双向链表与普通链表的区别在于,在链表中,一个节点只有链向下一个节点的链接,而双向链表中,链接是双向的:一个链向下一个元素,另一个链向前一个元素:

class Node {constructor(element) {this.element = elementthis.next = null // 保存前一个元素的引用this.prev = null // 保存后一个元素的引用}}class DoublyLinkedList {constructor() {this.length = 0 // 列表的元素个数this.head = null // 保存列表的第一项this.tail = null // 保存列表的最后一项}/*** 往指定位置插入元素* @param {number} position* @param {any} element*/insert(position, element) {// 检查越界值,position 在 0 到 this.length 的范围为有效值if (position < 0 || position > this.length) {return false // 表示插入元素失败}let node = new Node(element)if (position === 0) {// 往列表第一个位置插入元素if (this.length === 0) {// 往空列表中插入元素,则列表的头部和尾部均指向同一个元素this.head = nodethis.tail = node} else {// 往非空列表中插入元素let oldHead = this.headnode.next = oldHeadoldHead.prev = nodethis.head = node}} else if (position === this.length) {// 往列表末尾添加元素let oldTail = this.tailoldTail.next = nodenode.prev = oldTailthis.tail = node} else {// 从列表中间插入元素let previous = this.headlet current = this.head.nextfor (let i = 1; i < this.length; i++) {previous = currentcurrent = current.next}previous.next = nodecurrent.prev = nodenode.prev = previousnode.next = current}this.length++return true}/*** 从指定位置删除元素* @param {number} position*/removeAt(position) {// 检查越界值if (position < 0 || position >= this.length) {return null}let resultif (position === 0) {// 删除第一个位置的元素result = this.headif (this.length === 1) {// 原来的列表中仅有一个元素this.head = nullthis.tail = null} else {let oldHead = this.head// 将 this.head 改变 this.head 的下一个元素this.head = oldHead.nextthis.head.prev = null}} else if (position === this.length - 1) {// 删除的是最后一个位置的元素let oldTail = result = this.tailthis.tail = oldTail.prevthis.tail.next = null} else {let current = this.headlet previous = nullfor(let i = 1; i <= position ; i++) {previous = currentcurrent = current.next}result = currentprevious.next = current.nextcurrent.next.prev = previous}this.length--return result.element}}
