// 封装一个双向链表
function DoublyLinkedList() {
// 内部属性
this.head = null;
this.tail = null;
this.length = 0;
// 内部类,存放节点的数据和指针
function Node(data) {
this.data = data;
this.prev = null;
this.next = null;
}
// append 向链表的最后添加节点
DoublyLinkedList.prototype.append = function (data) {
let newNode = new Node(data);
if (!this.length) {
this.head = newNode;
} else {
newNode.prev = this.tail;
this.tail.next = newNode;
}
this.tail = newNode;
this.length++;
return this.length
}
// toString
DoublyLinkedList.prototype.toString = function () {
return this.backwardString()
}
// backwardString 往后遍历得到一个字符串
DoublyLinkedList.prototype.backwardString = function () {
let current = this.head;
let str = '';
while (current) {
str += current.data + ' ';
current = current.next;
}
return str
}
// forwardString 往前遍历得到一个字符串
DoublyLinkedList.prototype.forwardString = function () {
let previous = this.tail;
let str = '';
while (previous) {
str += previous.data + ' ';
previous = previous.prev;
}
return str
}
// insert 向链表中插入一个节点
DoublyLinkedList.prototype.insert = function (position, data) {
// 越界判断
if (position < 0 || position > this.length) return false;
// 创建一个节点
let newNode = new Node(data);
// 链表长度为0时
if (this.length == 0) {
this.head = newNode;
this.tail = newNode;
this.length++;
return true
}
// 插入到头部
if (position === 0) {
newNode.next = this.head;
this.head.prev = newNode;
this.head = newNode;
} else if (position === this.length) {
// 插入到尾部
newNode.prev = this.tail;
this.tail.next = newNode;
this.tail = newNode;
} else {
// 插入到其它位置
let current = this.head;
let 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
}
// removeAt 通过索引删除相应的节点
DoublyLinkedList.prototype.removeAt = function (position) {
// 越界判断
if (position < 0 || position >= this.length) return false;
let current = this.head;
// 如果只有一个节点时
if (this.length === 1) {
this.head = null;
this.tail = null;
this.length--;
return current.data
}
// 删除头部节点
if (position === 0) {
this.head = this.head.next;
this.head.prev = null;
} else if (position === this.length - 1) {
// 删除尾部节点
current = this.tail;
this.tail = this.tail.prev;
this.tail.next = null;
this.length--;
} else {
// 删除其它节点
if (position < this.length / 2) {
let index = 0;
while (index++ < position) {
current = current.next
}
} else {
let index = this.length - 1;
while (index-- > position) {
current = current.prev
}
}
current.prev.next = current.next;
current.next.prev = current.prev;
}
this.length--;
return current.data
}
// remove 通过信息删除相应的节点
DoublyLinkedList.prototype.remove = function (data) {
// 如果只有一个节点时
if (this.length === 1) {
this.head = null;
this.tail = null;
this.length--;
return true
}
// 删除头部节点
if (this.head.data === data) {
this.head = this.head.next;
this.head.prev = null;
this.length--;
return true
} else if (this.tail.data === data) {
// 删除尾部节点
this.tail = this.tail.prev;
this.tail.next = null;
this.length--
return true
} else {
// 删除其它节点
let current = this.head;
let previous = null;
while (current) {
previous = current;
current = current.next;
if (current && current.data === data) {
previous.next = current.next;
current.next.prev = previous;
this.length--;
return true
}
}
return false
}
}
// get 通过索引获取相应节点的信息
DoublyLinkedList.prototype.get = function (position) {
// 越界判断
if (position < 0 || position >= this.length) return null;
if (position < this.length / 2) { // 从前往后遍历
let current = this.head;
let index = 0;
while (index++ < position) {
current = current.next;
}
return current.data
} else { // 从后往前遍历
let current = this.tail;
let index = this.length - 1;
while (index-- > position) {
current = current.prev;
}
return current.data
}
}
// indexOf 通过节点的信息获取到相应的索引,没有的话返回-1
DoublyLinkedList.prototype.indexOf = function (data) {
if (this.tail.data === data) {
return this.length - 1
}
let current = this.head;
let index = 0;
while (current) {
if (current.data === data) {
return index
}
current = current.next;
index++;
}
return -1;
}
// update 修改节点的信息
DoublyLinkedList.prototype.update = function (position, newData) {
// 越界判断
if (position < 0 || position >= this.length) return false;
if (position < this.length / 2) { // 从前往后遍历
let current = this.head;
let index = 0;
while (index++ < position) {
current = current.next
}
current.data = newData;
} else { // 从后往前遍历
let current = this.tail;
let index = this.length - 1;
while (index-- > position) {
current = current.prev;
}
current.data = newData;
}
return true;
}
// isEmpty 判断链表是否为空
DoublyLinkedList.prototype.isEmpty = function () {
return this.length == 0
}
// size 查看链表的长度
DoublyLinkedList.prototype.size = function () {
return this.length
}
// getHead 获取链表第一个节点
DoublyLinkedList.prototype.getHead = function(){
return this.head.data
}
// getTail 获取链表最后节点
DoublyLinkedList.prototype.getTail = function(){
return this.tail.data
}
}
// ------ 测试--------
let d_list = new DoublyLinkedList();
d_list.append('帅的');
d_list.append('漂亮');
d_list.append('美德');
d_list.append('人才');
console.log(d_list);
console.log(d_list.backwardString());
console.log(d_list.forwardString());
console.log(d_list.insert(0, 'aa'));
console.log(d_list.insert(3, 'bb'));
console.log(d_list.insert(6, 'cc'));
console.log(d_list.toString());
// console.log(d_list.removeAt(6));
// console.log(d_list.get(0));
// console.log(d_list.indexOf('cc'));
// console.log(d_list.remove('aa'));
// console.log(d_list.remove('bb'));
// console.log(d_list.remove('cc'));
// console.log(d_list.remove('33'));
// console.log(d_list.toString());
// console.log(d_list.update(2, '33'));
// console.log(d_list.toString());
// console.log(d_list.isEmpty());
// console.log(d_list.size());
// console.log(d_list.getHead());
// console.log(d_list.getTail());