双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>双向链表</title>
</head>
<body>
<script>
function DoublyLinkedList() {
this.head = null
this.tail = null
this.length = 0
}
function Node(data) {
this.pre = null
this.data = data
this.next = null
}
//append向链表尾部添加节点
DoublyLinkedList.prototype.append = function (data) {
var newNode = new Node(data)
if (this.length == 0) {
this.head = newNode
this.tail = newNode
} else {
newNode.pre = this.tail
this.tail.next = newNode
this.tail = newNode
}
this.length++
}
//insert根据位置插入节点
DoublyLinkedList.prototype.insert = function (data, position) {
if (position < 0 || position > this.length) return false
var newNode = new Node(data)
if (this.length == 0) {
this.head = newNode
this.tail = newNode
} else {
if (position == 0) {
newNode.next = this.head
this.head.pre = newNode
this.head = newNode
} else if (position == this.length) {
newNode.pre = this.tail
this.tail.next = newNode
this.tail = newNode
} else {
var current = this.head
var index = 0
while (index++ < position) {
current = current.next
}
newNode.next = current
newNode.pre = current.pre
current.pre.next = newNode
current.pre = newNode
}
}
this.length++
return true
}
//get 根据位置获取节点数据
DoublyLinkedList.prototype.get = function (position) {
if (position < 0 || position >= this.length) return false
var index = 0
var current = this.head
if (index++ < position) {
current = current.next
}
return current.data
}
//indexOf根据data,返回节点位置
DoublyLinkedList.prototype.indexOf = function (data) {
var current = this.head
var index = 0
while (current) {
if (current.data == data) {
return index
}
current = current.next
index++
}
return -1
}
//update找到节点,修改数据
DoublyLinkedList.prototype.update = function (data, position) {
if (position < 0 || position >= this.length) return false
var current = this.head
var index = 0
while (index++ < position) {
current = current.next
}
current.data = data
return true
}
//removeAt方法,根据位置删除节点
DoublyLinkedList.prototype.removeAt = function (position) {
if (position < 0 || position >= this.length) return null
var current = this.head
if (this.length == 1) {
this.head = null
this.tail = null
} else {
if (position == 0) {
this.head.next.pre = null
this.head = this.head.next
} else if (position == this.length - 1) {
this.tail.pre.next = null
this.tail = this.tail.pre
} else {
var index = 0
while (index++ < position) {
current = current.next
}
current.pre.next = current.next
current.next.pre = current.pre
}
}
this.length--
return current.data
}
//romve方法,根据数据删除节点
DoublyLinkedList.prototype.remove=function(data){
var position=this.indexOf(data)
return this.removeAt(position)
}
//isEmpty方法,判断链表是否为空
DoublyLinkedList.prototype.isEmpty=function(){
return this.length==0
}
//size方法,判断链表是否为空
DoublyLinkedList.prototype.size=function(){
return this.length
}
//getFirstData方法,获取第一个元素数据
DoublyLinkedList.prototype.getFirstData=function(){
return this.head.data
}
//getLastData方法,获取最后一个元素数据
DoublyLinkedList.prototype.getLastData=function(){
return this.tail.data
}
//forwardString方法,向前遍历数据
DoublyLinkedList.prototype.forwardString = function () {
var current = this.tail
var resultString = ""
while (current) {
resultString += current.data + '_'
current = current.pre
}
return resultString
}
//backwardString方法,向后遍历数据
DoublyLinkedList.prototype.backwardString = function () {
var current = this.head
var resultString = ""
while (current) {
resultString += current.data + '_'
current = current.next
}
return resultString
}
//toString方法
DoublyLinkedList.prototype.toString = function () {
return this.backwardString()
}
var dll = new DoublyLinkedList()
dll.append('a')
dll.append('b')
dll.append('c')
dll.append('d')
dll.insert("aa", 1)
dll.insert("dd", 5)
console.log(dll)
console.log(dll.backwardString())
console.log(dll.indexOf('dd'))
dll.update("cc", 3)
dll.removeAt(0)
dll.remove('dd')
console.log(dll.toString())
console.log(dll.get(2))
console.log(dll.isEmpty())
console.log(dll.size())
console.log(dll.getFirstData())
console.log(dll.getLastData())
</script>
</body>
</html>