文章目录
一、什么是双向链表?
其实上一节我们说的链表是单向链表.而双向链表的区别在于:
- 既可以
从头遍历到尾
,也可以从尾遍历到头
- 一个节点既有
指向前一个元素的引用
,也有一个指向后一个元素的引用
当然他也有一些缺点:
- 每次在
插入或删除
某个节点时,需要处理四个引用,而不是两个 - 相对于单向链表,必然占用的
空间内存更大
一些
但这些缺点和我们使用起来的方便程度相比,是微不足道的
class DoubleNode {
constructor(data){
this.data = data
this.prev = null
this.next = null
}
}
class DoubleLinkedList{
constructor() {
this.head = null
this.tail = null
this.length = 0
}
// 操作方法
// 添加一个新的项
append(data) {
let newNode = new DoubleNode(data)
if(!this.head){
this.head = newNode
this.tail = newNode
}else{
newNode.prev = this.tail
this.tail.next = newNode
this.tail = newNode
}
this.length +=1
}
// 特定位置插入一个元素
insert(data, position){
if(position < 0 || position > this.length) return false
let newNode = new DoubleNode(data)
if(this.length === 0){
this.head = newNode
this.tail = newNode
}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 index = 0
let curNode = this.head
while(index++ < position){
curNode = curNode.next
}
newNode.prev = curNode.prev
newNode.next = curNode
curNode.prev.next = newNode
curNode.prev = newNode
}
}
this.length += 1
return true
}
// 获取对应位置元素
get(position){
if(position < 0 || position >= this.length) return null
let index = 0
let curNode = this.head
while(index++ < position){
curNode = curNode.next
}
return curNode.data
}
// 返回元素在链表中的位置,没有的话返回 -1
indexOf(data){
if(this.length === 0) return -1
let curNode = this.head
let index = 0
while(curNode.next){
if(curNode.data === data){
return index
}
index += 1
curNode = curNode.next
}
return -1
}
// 修改某个位置元素
update(position, data){
if(position < 0 || position >= this.length) return false
let curNode = this.head
let index = 0
while(index++ < position){
curNode = curNode.next
}
curNode.data = data
return true
}
// 删除某个位置的项
removeAt(position){
if(position < 0 || position >= this.length) return false
let curNode = 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){
curNode = this.tail
this.tail.prev.next = null
this.tail = this.tail.prev
}else{
let index = 0
while(index++ < position){
curNode = curNode.next
}
curNode.prev.next = curNode.next
curNode.next.prev = curNode.prev
}
}
this.length -= 1
return curNode.data
}
// 删除某个项
remove(data){
let position = this.indexOf(data)
if(position === -1) return false
return this.removeAt(position)
}
isEmpty(){
return this.length === 0
}
size(){
return this.length
}
// toString
toString(){
let curNode = this.head
let str = ''
while(curNode){
str += curNode.data + ' '
curNode = curNode.next
}
return str
}
// forwardString
forwardString(){
let curNode = this.tail
let str = ''
while(curNode){
str += curNode.data + ' '
curNode = curNode.prev
}
return str
}
// backwardString
backwardString(){
let curNode = this.head
let str = ''
while(curNode){
str += curNode.data + ' '
curNode = curNode.next
}
return str
}
}
let h = new DoubleLinkedList()
h.append('df')
h.append('2')
// h.append('3')
h.insert('dfd',2)
h.append('dfd',3)
h.update(10, 11)
// h.append('4')
console.log(h.remove('2'))
// console.log(h.get(1))
console.log(h.toString())