//双向链表的常用操作
function DoubleLinkedList() {
function Node(element) {
this.prev = null
this.next = null
this.node = element
}
this.length = 0
this.head = null
this.end = null
// append(element) 追加元素
DoubleLinkedList.prototype.append = function (element) {
let node = new Node(element)
if (this.length === 0) {
this.head = node
this.end = node
} else {
node.prev = this.end
this.end.next = node
this.end = node
}
this.length += 1
}
//insert(position,element)
DoubleLinkedList.prototype.insert = function (position, element) {
if (position < 0 || position > this.length) return false
let node = new Node(element)
if (this.length == 0) {
this.head = node
this.end = node
} else if (position == this.length - 1) {
node.prev = this.end
this.end.next = node
this.end = node
} else {
if (position == 0) {
node.next = this.head
this.head.prev = node
this.head = node
} else {
let current = this.head,
index = 0,
keepNode
while (index++ < position) {
keepNode = current
current = current.next
}
keepNode.next = node
node.prev = keepNode
node.next = current
current.prev = node
}
}
this.length += 1
}
//get()
DoubleLinkedList.prototype.get = function (position) {
if (Math.abs(position) > this.length) return null
if (position >= 0) {
let current = this.head,
index = 0
while (index++ < position) {
current = current.next
}
return current.node
}
if (position <= 0) {
let current = this.end,
index = 0
while (index++ < Math.abs(position)) {
current = current.prev
}
return current.next.node
}
}
//indexOf()
DoubleLinkedList.prototype.indexOf = function (element) {
let current = this.head,
index = 0
while (current) {
if (current.node == element) {
return index
}
current = current.next
index += 1
}
return -1
}
//update()
DoubleLinkedList.prototype.update = function (position, element) {
if (Math.abs(position) > this.length) return null
if (position >= 0) {
let current = this.head,
index = 0
while (index++ < position) {
current = current.next
}
current.node = element
}
if (position < 0) {
let current = this.end,
index = 0
while (index++ < Math.abs(position)) {
current = current.prev
}
current.next.node = element
}
}
//removeAt()
DoubleLinkedList.prototype.removeAt = function (position) {
if (position > this.length) return null
if (position >= 0) {
if (position == 0) {
this.head = this.head.next
this.head.prev = null
} else if (position == this.length - 1) {
this.end = this.end.prev
this.end.next = null
} else {
let current = this.head,
index = 0,
keepNode
while (index++ < position) {
keepNode = current
current = current.next
}
current.next.prev = keepNode
keepNode.next = current.next
}
}
if (position < 0) {
if (Math.abs(position) == this.length) {
this.head = this.head.next
this.head.prev = null
} else {
let current = this.end,
index = 0,
keepNode
while (index++ < Math.abs(position)) {
keepNode = current
current = current.prev
}
keepNode.prev = current.prev
current.prev.next = keepNode
}
}
this.length -= 1
}
//remove
DoubleLinkedList.prototype.remove = function (element) {
let index = this.indexOf(element)
this.removeAt(index)
}
//isEmpty
DoubleLinkedList.prototype.isEmpty = function () {
return !Boolean(this.length)
}
// size
DoubleLinkedList.prototype.size = function() {
return this.length
}
//toString
DoubleLinkedList.prototype.toString = function () {
let current = this.head,
result = '',
comma
while (current) {
comma = current.next ? ',' : ''
result += current.node + comma
current = current.next
}
return result
}
// forwardString()
DoubleLinkedList.prototype.forwardString = function () {
let current = this.end,
result = '',
comma
while (current) {
comma = current.prev ? ',' : ''
result += current.node + comma
current = current.prev
}
return result
}
}
const doubleLinkedList = new DoubleLinkedList()