双向链表中共有两指针,一个指向上一个元素,一个指向下一个元素。
js实现双向链表:
//基于数组实现双向链表
function DoublyLinkedList() {
var Node = function(element){
this.element = element;
this.next = null; //指向下一个元素的指针
this.prev = null; //指向上一个指针的元素
};
var length = 0; //链表的长度
var head = null; //表头
var tail = null; //表尾
//在任意位置添加元素
this.insert = function(position, element){
//检查position是否在临界点内
if (position >= 0 && position <= length)
{
var node = new Node(element),//实例化要添加的元素
current = head,//设置起点
previous,//上一个元素
index = 0;//从0开始的索引
if (position === 0)
{
//在第一个位置添加
if (!head)
{ //如果先前链表为空,添加的元素既是表头又是表尾
head = node;
tail = node;
}
else
{
node.next = current;//设置新增元素向下指针指向当前的表头
current.prev = node; //设置当前表头的向上指针指向新增元素
head = node;//设置表头为新增元素
}
}
else if (position === length)
{
//最后一项新增
current = tail; //设置当前项为最后一项
current.next = node;//当前项(最后一项)的向下指针指向新增元素
node.prev = current;//新增元素的指针指向当前元素
tail = node;//设置表尾为新增元素
}
else
{ //在其他位置新增
while (index++ < position)
{ //遍历找到当前项
previous = current;//找到插入位置的上项
current = current.next;//找到插入位置的下一项
}
node.next = current; //设置新增元素是向下指针指向下一项
previous.next = node;//上一项的向下指针指向当前元素
current.prev = node; //下一项的指针向上指针指向新增项
node.prev = previous; //新增项的向上指针指向上一项
}
//更新链表的长度
length++;
return true;
}
else
{
//postion不在临界点内,返回false
return false;
}
};
//从特定位置移除一个元素
this.removeAt = function(position){
//检查越界值
if (position > -1 && position < length){
var current = head,
previous, //定义上一个元素
index = 0;
//移除第一项
if (position === 0)
{
head = current.next; //设置表头为下一项
//如果只有一项,更新tail
if (length === 1){
tail = null;
}
else
{
head.prev = null;
}
}
else if (position === length-1)
{ //移除最后一项
current = tail; //找到表尾
tail = current.prev;//设置表尾为上一项
tail.next = null;//向下指针为空
}
else
{
while (index++ < position)
{ //其他项
previous = current;//找到要移除的上一次项
current = current.next;//找到当前项
}
//将previous与current的下一项链接起来——跳过current
previous.next = current.next; //设置上一项的向下指针指向下一项
current.next.prev = previous; //设置移除项的下一项向上指针指向上一项
}
//更新链表的长度
length--;
//返回移除项
return current.element;
}
else
{
return null;
}
};
/toString方法
this.toString = function(){
var current = head, //从表头开始
string = ''; //定义一个string,用于拼接链表元素
while (current) { //从表头开始遍历链表,拼接链表元素
string = current.element;
current = current.next;
}
return string;
};
//indexOf方法,接收一个元素的值,如果存在,就返回该元素的所在位置,否则返回-1
this.indexOf = function(element){
var current = head, //设置起点为表头
index = 0;//index初始值为0
while (current) { //从表头开始遍历,找到和接收值一样的元素,返回
if (element === current.element) {
return index; //返回该元素的位置,结束遍历
}
index++;
current = current.next;
}
//如果不存在,返回-1
return -1;
};
/*通过indexOf方法和remover方法,可以实现移除一个特定值的元素
*/
移除一个特定值的元素
this.remove = function(element){
//先获取该元素的位置
var index = this.indexOf(element);
//通过位置移除该元素
return this.removeAt(index);
};
//isEmpty方法,判断链表是否为空
this.isEmpty = function() {
return length === 0;
};
//size方法,返回链表的长度
this.size = function() {
return length;
};
//getHead方法,查找表头元素
this.getHead = function(){
return head;
};
}