1.单向链表前进容易,回退比较困难,所以需要双向链表。
2.双向链表示意
3.常见操作
双向链表常见的操作(方法):
- append(element):向链表尾部添加一个新的项;
- inset(position,element):向链表的特定位置插入一个新的项;
- get(element):获取对应位置的元素;
- indexOf(element):返回元素在链表中的索引,如果链表中没有元素就返回-1;
- update(position,element):修改某个位置的元素;
- removeAt(position):从链表的特定位置移除一项;
- isEmpty():如果链表中不包含任何元素,返回trun,如果链表长度大于0则返回false;
- size():返回链表包含的元素个数,与数组的length属性类似;
- toString():由于链表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值;
- forwardString():返回正向遍历节点字符串形式;
- backwordString():返回反向遍历的节点的字符串形式;
4.注意事项
- append方法注意分类拆入的是第一个点还是其他点
- 打印字符串根据遍历放向,current初值设为head 或者 tail
- 插入指定位置,首先考虑到越界判断。然后对插入的情况进行分类:插入空链表,插入头部,插入尾部,插入其他地方
- get方法的越界判断,查询位置不能等于this.length。
- indexOf while(current)遍历,退出条件是找到了,返回index。或者遍历完没找到自动退出,返回-1
- update 就先找到,再更新
- 删除节点,一个节点没有引用指向,就等于被删除了。首先进行越界判断,然后分情况讨论。删除的链表只有一个节点,删除的链表大于1时,第一个节点,任意的节点,最后一个节点
- 根据值删除元素,先获取元素下标,再removeAt
5.代码实现
function Dublelink() {
//内部类节点
function Node(data) {
this.data = data;
this.prev = null;
this.next = null
}
//属性
this.head = null;
this.tail = null;
this.length = 0;
//方法
//1.append
Dublelink.prototype.append = function(data) {
//1.创建节点接收数据
var newnode = new Node(data);
//2.判断插入位置,分类讨论
if(this.length == 0) {
this.head =newnode;
this.tail = newnode;
}else {
newnode.prev = this.tail;
this.tail.next = newnode;
this.tail = newnode;
}
//3.长度+1
this.length++;
}
//2.转成字符串
//2.1 toString 一般默认是顺序遍历
Dublelink.prototype.toString = function() {
return this.backwardString();
}
//2.2 forwardString 向前遍历
Dublelink.prototype.forwardString = function() {
//定义遍量
var current = this.tail;
var result = ' ';
//顺序遍历
while(current) {
result += current.data + ' ';
current = current.prev;
}
return result;
}
//2.3 backwardString 向后遍历
Dublelink.prototype.backwardString = function() {
//定义遍量
var current = this.head;
var result = ' ';
//顺序遍历
while(current) {
result += current.data + ' ';
current = current.next;
}
return result;
}
//3.insert方法
Dublelink.prototype.insert = function(position, data) {
//越界判断
if(position < 0 || position > this.length) return false;
//接受数据
var node = new Node(data);
//若插入空表
if(this.length == 0) {
this.head = node;
this.tail = node;
}else if (position == 0) { //若插入头部
node.next = this.head;
this.head.prev = node;
this.head = node;
}else if (position == this.length) { //插入尾部
node.prev = this.tail;
this.tail.next = node;
this.tail = node;
}else { //其他位置
var index = 0;
var current = this.head;
while(index++ < position) {
current = current.next;
}
node.next = current;
node.prev = current.prev;
current.prev.next = node;
current.prev = node;
}
//长度+1
this.length++;
return true;
}
//4.get方法
Dublelink.prototype.get = function(position) {
//越界判断,这里的position不能等于length
if (position < 0 || position >= this.length) return null;
//获取元素位置
var current = this.head;
var index = 0;
while(index++ < position) {
current = current.next;
}
return current.data;
}
//5.indexOf方法
Dublelink.prototype.indexOf = function(data) {
var current = this.head;
var index = 0;
while(current) {
if(current.data == data){
return index;
}
current = current.next;
index++;
}
return -1;
}
//6.update方法
Dublelink.prototype.update = function(position, newdata) {
//越界判断
if(position < 0 || position >= this.length) return false;
//遍历
var current = this.head;
var index = 0;
while(index++ < position) {
current = current.next;
}
//修改值
current.data = newdata;
return true;
}
//7.removeAt方法
Dublelink.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.next.prev = null;
this.head = this.head.next;
}else if(position == this.length-1){ //删除正常表的最后一个节点
current = this.tail; //为了返回删除的节点,保存一下
this.tail.prev.next = null;
this.tail = this.tail.prev;
}else {
//删除正常表任意节点
var index = 0;
while(index++ < position) {
current = current.next;
}
current.prev.next = current.next;
current.next.prev = current.prev
}
}
//长度-1
this.length--;
//返回删除值
return current.data;
}
//8.remove方法
Dublelink.prototype.remove = function(data) {
var index = this.indexOf(data);
return this.removeAt(index);
}
//9.isEmpty方法
Dublelink.prototype.isEmpty= function() {
return this.length == 0;
}
//9.size方法
Dublelink.prototype.size = function() {
return this.length;
}
//10.获取第一个元素
Dublelink.prototype.getHead = function() {
return this.head.data;
}
//11.获取最后一个元素
Dublelink.prototype.getTail = function() {
return this.tail.data;
}
}