1. 概念
双链表,每个数据节点中有两个指针,分别指向前驱和后继;
2. 特点
header
tail
指向头尾;- 由三个部分组成(头、尾、元素);
- 第一个节点前驱为
null
- 最后一个节点的后继为
null
3. 常用方法
append(ele)
-尾部插入;insert(position,ele)
- 特定位置插入;update(position,ele)
- 更新特定位置;removeAt(position)
- 删除位置上的某一项;remove(ele)
- 删除某一个元素;isEmpty()
- 判断链表是否为空;size()
- 返回链表中的数据长度;tostring()
- 打印链表中的数据;
4. 双链表实现
function DoubleList() {
// 构建数据
function Node(data) {
this.prev = null
this.data = data
this.next = null
}
// 外层标识
this.head = null
this.tail = null
this.length = 0
// 尾部添加方法
DoubleList.prototype.append = (data) => {
let newNode = new Node(data)
if (this.length == 0) {
this.head = newNode
this.tail = newNode
newNode.prev = null
} else {
// 改变指向
this.tail.next = newNode
newNode.prev = this.tail
this.tail = newNode
}
this.length++
}
DoubleList.prototype.insert = (position, dada) => {
if (position < 0 || position > this.length) {
return false
} else {
if (position == 0) {
this.head.prev = newNode
newNode.next = this.head;
this.head = newNode
} else if (position == this.length) {
this.tail.next = newNode
newNode.prev = this.tail
this.tail = newNode
} else {
let current = this.head
let index = 0
while (index < position) {
current = current.next
index++
}
current.prev.next = newNode
newNode.prev = current.prev
newNode.next = current
current.prev = newNode
}
}
this.length++
}
DoubleList.prototype.update = (position, data) => {
if (position < 0 || position > this.length) {
return false
}
let current = this.head
let index = 0
while (index < position) {
current = current.next
index++
}
current.data = data
return true
}
DoubleList.prototype.removeAt = (position) => {
if (position < 0 || position > this.length) {
return false
}
if (this.length == 1) {
this.head = null
this.tail = null
} else {
if (position == 0) {
this.head = this.head.next
this.head.prev = null
} else if (position == this.length) {
this.tail = this.tail.prev
this.tail.next = null
} else {
let current = this.head
let index = 0
while (index < position) {
current = current.next
index++
}
current.prev.next = current.next
current.next.prev = current.prev
}
}
this.length--
return true
}
DoubleList.prototype.remove = (data) => {
let current = this.head
let index = 0
while (current.data != data) {
current = current.next
index++
}
return this.removeAt(index)
}
DoubleList.prototype.isEmpty = () => {
return !this.length
}
DoubleList.prototype.size = () => {
return this.length
}
DoubleList.prototype.tostring = () => {
let current = this.head
let str = []
while (current) {
str += current.data + '\n'
current = current.next
}
return str
}
}
var list = new DoubleList();
list.append('1');
list.append('2');
list.append('3');
list.append('4');
list.append('5');
list.append('6');
list.update(3, '7')
console.log(list.size())
console.log(list.remove(2))
console.log(list.removeAt(3))
console.log(list.isEmpty());
console.log(list);
拓展 手写一个indexOf方法便于查找元素在链表中的位置
// 方式一
DoubleList.prototype.remove = (data) => {
let current = this.head
let index = 0
while (current.data != data) {
current = current.next
index++
}
return this.removeAt(index)
}
// 方式二
DoubleList.prototype.indexOf = (element) => {
let currentNode = this.head
let index = 0
while (index < this.length) {
if (currentNode.data === element) {
break;
}
currentNode = currentNode.next
index++
}
return index === this.length ? -1 : index
}
DoubleList.prototype.remove = (data) => {
return this.removeAt(this.indexOf(data))
}