JS实现链表

/**
 * 链表
 * @authors Your Name (you@example.org)
 * @date    2018-02-09 10:52:40
 * @version $Id$
 */


//链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素
//由一个存储元素本身的节点和一个指向下一个元素的引用(也成指针或者链接)组成。
//相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然而,
//链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何
//位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代表直到找到
//所需的元素。


function LinkedList(){
var Node = function(element){
this.element = element;
this.next = null;
};


var length = 0;
var head = null;


this.append = function(element){
var node = new Node(element), current;
if(head === null){
head = node;
}else{
current = head;
//循环列表,知道找到最后一项
while(current.next){
current = current.next;
}
//找到最后一项,将其next赋为node,建立连接
current.next = node;
}
length++;//跟新链表长度
}; //向列表尾部添加一个新的项
this.insert = function(position, element){
//检查越界值
if(position>-1 && position < length){
var node = new Node(element), current = head, previous, index=0;
if(position === 0){
node.next = current;
head = mode;
}else{
while(index++ < position){
previous = current;
current = current.next;//current是对postion所在位置的引用
}
previous.next = node;
node.next = current;
}
length++;//更新列表的长度
return true;
}else{
return false;
}
}; //向列表的特定位置插入一个新的项
this.removeAt = function(position){
//检查越界值
if(position > -1 && position < length){
var current = head, previous, index=0;
//移除第一项
if(position === 0){
head = current.next;
}else{
while(index++ < position){
previous = current;
current = current.next;
}
//将previous与current的下一项连接起来:跳过current,从而移除它
previous.next = current.next;
}
length--;
return current.element;
}else{
return null;
}
}; //从列表中特定位置移除一项
this.remove = function(element){
var index = this.indexOf(element);
return this.removeAt(index);
}; //从列表中移除一项
this.indexOf = function(element){
//这是小编自己写的
var node = new Node();
var current = head, index=0, length=0;
for(current){
current = current.next;
length++;
}
while(index++ < length){
if(element = node.element){
return index;
}
}
return -1;

//这是小片自己找的另一种更简洁一点的写法
var current = head, index = 0;
while(current){
if(element === current.element)
{
return index;
}
current = current.next;
index++;
}
return -1;
}; //返回元素在列表中的索引,如果列表中没有该元素则则返回-1
this.isEmpty = function(){
var current = head,
length = 0;
while(current){
current = current.next;
length++;
}
return length ==== 0;


}; //如果链表中不包含任何元素,返回true,如果链表长度大于0,则返回false
this.size = function(){
var current = head,
length = 0;
while(current){
current = current.next;
length++;
}
return length;
}; //返回链表包含的元素个数,与数组的length属性相似
this.toString = function(){
var current = head, string = '';


while(current){
string = current.element;
current = current.next;
}
return string;
}; //由于列表项使用了node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值
}




//双向链表
//这一节介绍双向链表。双向链表和普通链表的区别在于,在链表中,
//一个节点只有链向下一个节点的链接,而在双向链表中,链表是双向的:
//一个链向下一个元素,另一个链向前一个元素。
//
//与单向链表相比较,如果迭代列表时错过了要找的元素,就需要回到列表起点,
//重新开始迭代。这是双向链表的有点


function DoubleLinkedList(){
var Node = new function(element){
this.element = element;
this.pre = pre; //新增的
this.next = next;
};


var length = 0;
var head = null;
var tail = null; //新增的


this.insert = function(position, element){
//检查越界值
if(position >= 0 && position <= length){
var node = new Node(element),
current = head,
previous,
index = 0;


//在列表的第一个位置(列表的起点)插入第一个新元素。如果列表为空,只需要把head和tail都指向这个
//新节点。如果不为空,current变量将是对列表中第一个元素的引用。就像我们在链表中做的,把node.next
//设为current,而head将指向node(它将成为列表中的第一个元素)。不同的是,我们还需要为指向上一个元素
//的指针设一个值。current.pre指针将由指向null变为指向新元素(node)。node.pre已经是null,因此不需要
//更新。
if(position === 0){ //在第一个位置添加
if(!head){
head = node;
tail =node;
}else{
node.next = current;
current.pre = 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.pre = node; //新增的
node.pre = previous; //新增的
}


length++; //更新列表长度
return true; 


}else{
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.pre = null;
}
}else if(position === length - 1){ //移除最后一项
current = tail;
tail = current.pre;
tail.next = null;
}else{//移除中间的
while(index++ < position){
previous = current;
current = current.next;
}
//将previous与current的下一项连接起来
previous.next = current;
current = current.next;
}
length--;
return current.element;
}else{
return null;
}
};
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值