【数据结构与算法】双向链表
一.什么是双向链表?
双向链表,又称为双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表——维基百科
二.代码实现
<!--
* @Description: 双向链表的封装
* @Autor: wangxin
* @Date: 2020-05-30 06:40:13
* @LastEditors: Seven
* @LastEditTime: 2020-05-30 14:00:33
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 封装双向链表
function DoublyLinkedList() {
// 定义内部类用于创建节点
function Node(data) {
this.data = data
this.prev = null // 上一个节点引用
this.next = null // 下一个节点引用
}
// 定义属性
this.head = null // 头部引用
this.tail = null // 尾部引用
this.length = 0
// 1.append 在尾部追加数据
DoublyLinkedList.prototype.append = function (element) {
var newNode = new Node(element)
// 判断链表是否为空
if (this.length == 0) {
this.head = newNode
this.tail = newNode
} else {
this.tail.next = newNode
newNode.prev = this.tail
this.tail = newNode
}
this.length++
}
// 2.正向反向遍历
// 2.1.forwardString 正向遍历转成字符串的方法
DoublyLinkedList.prototype.forwardString = function () {
var current = this.head
var result = ''
while (current) {
result += current.data + ' '
current = current.next
}
return result
}
// 2.2.reverseString 反向遍历转成字符串的方法
DoublyLinkedList.prototype.reverseString = function () {
var current = this.tail
var result = ''
while (current) {
result += current.data + ' '
current = current.prev
}
return result
}
// 2.3.toString 正向遍历转成字符串的方法
DoublyLinkedList.prototype.toString = function () {
return this.forwardString()
}
// 3.insert 在任意位置插入
DoublyLinkedList.prototype.insert = function (position, element) {
// 1.判断越界问题
if (position < 0 || position > this.length) return false
// 2.创建新节点
var newNode = new Node(element)
// 3.插入元素
if (this.length === 0) {
this.head = newNode
this.tail = newNode
} else {
if (position === 0) {
// 插入位置为0
this.head.prev = newNode
newNode.next = this.head
this.head = newNode
} else if (position === this.length) {
// 插入最后的位置
newNode.prev = 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.prev = current.prev
current.prev.next = newNode
current.prev = newNode
}
}
this.length++
return true
}
// 4.get 获取指定位置数据
DoublyLinkedList.prototype.get = function (position) {
if (position < 0 || position >= this.length) return null
if (this.length / 2 > position) {
// 1.从头部开始查找
var current = this.head
var index = 0
while (index++ < position) {
current = current.next
}
return current.data
} else if (this.length / 2 <= position) {
// 2.从末尾开始查找
var current = this.tail
var index = this.length - 1
while (index-- > position) {
current = current.prev
}
return current.data
}
}
// 5.indexOf 返回指定数据的位置
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
}
// 6.updete 更新指定位置的数据
DoublyLinkedList.prototype.update = function (position, newData) {
if (position < 0 || position >= this.length) return false
if (this.length / 2 > position) {
// 1.从头开始查找
var current = this.head
var index = 0
while (index++ < position) {
current = current.next
}
current.data = newData
} else {
// 2.从尾开始查找
var current = this.tail
var index = this.length - 1
while (index-- > position) {
current = current.prev
}
current.data = newData
}
return true
}
// 7.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.prev = null
this.head = this.head.next
} else if (position === this.length - 1) {
current = this.tail
this.tail.prev.next = null
this.tail = this.tail.prev
} else {
// var current = this.head
var index = 0
while (index++ < position) {
current = current.next
}
current.next.prev = current.prev
current.prev.next = current.next
}
}
this.length -= 1
return current.data
}
// 8.remove 移除指定的数据
DoublyLinkedList.prototype.remove = function (data) {
var index = this.indexOf(data)
this.removeAt(index)
}
// 其他方法
// 9.isEmpty 是否为空
DoublyLinkedList.prototype.isEmpty = function () {
return this.length === 0
}
// 10.size 返回链表长度
DoublyLinkedList.prototype.size = function () {
return this.length
}
// 11.getHead 获取链表第一个元素
DoublyLinkedList.prototype.getHead = function () {
return this.head.data
}
// 12.getTail 获取链表最后一个元素
DoublyLinkedList.prototype.getTail = function () {
return this.tail.data
}
}
</script>
</body>
</html>