双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
特点 :
- 可以用一个head 和一个tail 分别指向头和尾的节点
- 每个节点都由三部分组成:前一个节点的指针(prev)/保存元素(item)/后一个节点的指针(next)
- 双向链表的第一个节点的prev是null
- 双向链表的最后节点的next是null
常用方法:
- append(data) 追加元素
- insert(position, data) 插入节点
- get(position) 查看元素
- indexOf(element) 返回元素在列表中的索引
- updata(position) 修改某个位置的元素
- remove(position/data) 从列表的特定位置(数据)移除一项
- isEmpty() 如果链表中不包含任何元素,返回true,否则为false
- size() 返回链表包含的元素个数,与数组的length类似
// 封装双向链表
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 (data) {
var newNode = new Node(data);
// 判断是否空链表
if (this.length === 0 ) {
this.head = newNode;
this.tail =newNode;
}else{
newNode.prev = this.tail;
// 更新尾指针
this.tail.next = newNode;
this.tail = newNode;
}
// 更新链表长度
this.length += 1
}
// 2 toString转字符串
DoublyLinkedList.prototype.toString = function () {
return this.backwardString()
}
// 2.2 forwardString方法
DoublyLinkedList.prototype.forwardString = function () {
var current = this.tail;
var result = '';
// 依次向前遍历各个节点
while (current) {
result += current.data + " " ;
current = current.prev;
}
return result
}
// 2.2 backwardString方法
DoublyLinkedList.prototype.backwardString = function () {
var current = this.head;
var result = '';
// 依次向前遍历各个节点
while (current) {
result += current.data + " " ;
current = current.next;
}
return result
}
// 3 insert插入节点
DoublyLinkedList.prototype.insert = function (position, data) {
// 1 对position进行越界判断
if (position < 0 || position >= this.length) return false
// 2 根据data创建节点
var newNode = new Node(data)
// 3 判断链表是否为空
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) {
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 += 1;
}
// 4 get方法
DoublyLinkedList.prototype.get = function (position) {
// 1 对position进行越界判断
if (position < 0 || position >= this.length) return false
// 获取元素
var index = 0;
var current = this.head;
while (index++ < position) {
current = current.next
}
return current.data
}
// 5 indexOf(element)返回元素在列表中的索引
DoublyLinkedList.prototype.indexOf = function (element) {
var current = this.head;
var index = 0;
while (current) {
if (current.data === element) {
return index
}
current = current.next;
index += 1;
}
return false
}
// 6 updata(position)修改某个位置的元素
DoublyLinkedList.prototype.updata = function (position, newdata) {
// 由于又position信息,故需要进行越界判断
if (position < 0 || position >= this.length) return false
var current = this.head;
var index = 0;
while (index++ < position) {
current = current.next;
}
current.data = newdata;
}
// 7 removeAt(position)从列表的特定位置移除一项
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 = 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
}
// 其它情况
else {
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(element)从列表中移除一项
DoublyLinkedList.prototype.remove = function (element) {
// 查找位置
var position = this.indexOf(element);
// 删除
return this.removeAt(position);
}
// 9 isEmpty() 如果链表中不包含任何元素,返回true,否则为false
DoublyLinkedList.prototype.isEmpty = function () {
return this.length === 0
}
// 10 size() 返回链表包含的元素个数,与数组的length类似
DoublyLinkedList.prototype.size = function () {
return this.length
}
}
// 测试代码
var list = new DoublyLinkedList();
list.append('111');
list.append('222');
list.append('333');
console.log(list.toString());
list.remove('111');
console.log(list.toString());
本文详细介绍了双向链表的概念及其特点,包括其数据结构和常用操作如追加、插入、获取、查找、更新和删除元素。还提供了一个JavaScript实现的双向链表类,包含了各种操作方法,并通过示例展示了其用法。

4032

被折叠的 条评论
为什么被折叠?



