<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.追加方法
DoublyLinkedList.prototype.append = function(data) {
// 创建新节点
var newNode = new Node(data);
// 判断长度是否为0
if (this.length === 0) {
this.head = newNode;
this.tail = newNode;
} else {
newNode.prev = this.tail;
this.tail.next = newNode;
this.tail = newNode;
}
// 长度+1
this.length += 1;
};
// 2.toString 方法
DoublyLinkedList.prototype.toString = function() {
return this.backwardString();
};
// 2.2 forwardString 方法
DoublyLinkedList.prototype.forwardString = function() {
// 定义变量
var current = this.tail;
var resultString = "";
// 依次向前遍历
while (current) {
resultString += current.data + " ";
current = current.prev;
}
return resultString;
};
// 2.3 backwardString 方法
DoublyLinkedList.prototype.backwardString = function() {
// 定义变量
var current = this.head;
var resultString = "";
// 依次向后遍历
while (current) {
resultString += current.data + " ";
current = current.next;
}
return resultString;
};
// 3 insert 方法
DoublyLinkedList.prototype.insert = function(position, data) {
// 越界判断
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) {
//判断position是否为0
newNode.next = this.head;
this.head.prev = newNode;
this.head = newNode;
} else if (position == this.length) {
// position == this.length
newNode.prev = this.tail;
this.tail.next = newNode;
this.tail = newNode;
} else {
// 其他情况
if (position < this.length / 2) {
// 从前到后查找指定位置插入
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;
} else {
// 从后到前查找指定位置插入
var current = this.tail;
var index = this.length;
while (index-- > position) {
current = current.prev;
}
newNode.prev = current;
newNode.next = current.next;
current.next.prev = newNode;
current.next = newNode;
}
}
}
// 链表长度+1
this.length += 1;
};
// 4. get方法
DoublyLinkedList.prototype.get = function(position) {
// 越界判断
if (position < 0 || position >= this.length) return false;
if (position < this.length / 2) {
// 从前往后查找
var index = 0;
var current = this.head;
while (index++ < position) {
current = current.next;
}
return current.data;
} else {
//从后往前查找
var index = this.length - 1;
var current = this.tail;
while (index-- > position) {
current = current.prev;
}
return current.data;
}
};
// 5. indexOf 方法
DoublyLinkedList.prototype.indexOf = function(data) {
var index = 0;
var current = this.head;
while (current) {
if (current.data == data) return index;
current = current.next;
index += 1;
}
return -1;
};
// 6. update 方法
DoublyLinkedList.prototype.update = function(position, data) {
// 越界判断
if (position < 0 || position > this.length) return false;
// 通过position判断从前还是从后查找
if (position < this.length / 2) {
//从前往后找
// 定义变量
var index = 0;
var current = this.head;
// 循环查找
while (index++ < position) {
current = current.next;
}
// 修改指定位置的数据
current.data = data;
} else {
// 从后往前找
// 定义变量
var index = this.length - 1;
var current = this.tail;
// 循环查找
while (index-- > this.length) {
current = current.prev;
}
// 修改指定位置的数据
current.data = data;
}
return true;
};
// 7. removeAt方法
DoublyLinkedList.prototype.removeAt = function(position) {
// 越界判断
if (position < 0 || position >= this.length) return null;
// position === 0
if (position == 0) {
if (this.length == 1) {
this.head = null;
this.tail = null;
} else {
this.head.next.prev = null;
this.head = this.head.next;
}
} else if (position == this.length - 1) {
this.tail.prev.next = null;
this.tail = this.tail.prev;
} else {
// 通过position判断是从前还是从后查找
if (position < this.length / 2) {
//从前往后找\
// 定义变量
var current = this.head;
var index = 0;
// 循环找到指定位置
while (index++ < position) {
current = current.next;
}
// 删除指定位置的元素
current.prev.next = current.next;
current.next.prev = current.prev;
} else {
//从后往前找
// 定义变量
var current = this.tail;
var index = this.length - 1;
// 循环找到指定位置
while (index-- > position) {
current = current.prev;
}
// 删除指定位置的元素
current.prev.next = current.next;
current.next.prev = current.prev;
}
}
// 链表长度减一
this.length -= 1;
return current.data;
};
// 8. remove 方法
DoublyLinkedList.prototype.remove = function(data) {
// 获取data对应的位置
var position = list.indexOf(data);
// 从指定位置删除该元素
return list.removeAt(position);
};
// 9.isEmpty 方法
DoublyLinkedList.prototype.isEmpty = function() {
return this.length === 0
}
// 10. size 方法
DoublyLinkedList.prototype.size = function() {
return this.length
}
}
var list = new DoublyLinkedList();
</script>