js实现链表

链表

数组不总是组织数据的最佳数据结构,原因如下。在很多编程语言中,数组的长度是固定
的,所以当数组已被数据填满时,再要加入新的元素就会非常困难。在数组中,添加和删
除元素也很麻烦,因为需要将数组中的其他元素向前或向后平移,以反映数组刚刚进行了
添加或删除操作。然而,JavaScript 的数组并不存在上述问题,因为使用 split() 方法不需
要再访问数组中的其他元素了-
JavaScript 中数组的主要问题是,它们被实现成了对象,与其他语言(比如 C++ 和 Java)
的数组相比,效率很低

链表是由一组节点组成的集合,每个节点都使用一个对象的引用指向它的后继,指向另一个节点的引用叫做链。

Node类:用来表示节点
linkedList:提供插入、删除、显示元素的方法,以及一些其他方法

Node类:包含两个属性:
element:当前数据
next:用来指向下个节点的链接

单链表的实现

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

var linkedList = function(){
	this.head = new Node('head');
}
var linkedList.prototype = {
	//查找一个元素
	find:function(item){
		//遍历整个链表,获取头节点
		var currentNode = this.head;
		while(currentNode.element != item && currentNode.next != null){
			currentNode = currentNode.next;
		}
		return currentNode;
	}
	//查找一个元素的前一个元素
	findPrevious:function(item){
		var currentNode = this.head;
		while(currentNode.next.element != item && currentNode.next!=null){
			currentNode = current.next;
		}
		return curretnNode;
	}
	//添加一个元素
	//element要插入的元素
	//item 要插入在什么元素的后面
	//需要找到前一个元素,并且判断前一个元素是否为空  
	//需要一个辅助函数find
	insert:function(element,item){
		var nowNode = new Node(element);
		var currentNode = this.find(item);
		nowNode.next = currentNode.next;
		currentNode.next = nowNode;
	}
	
	//删除一个元素
	remove:function(item){
		var preNode =this.findPrevious(item);
		if(preNode!=null){
			preNode.next = preNode.next.next;
		}		
	}
	
	//显示链表的元素
	display:function(){
	var str = '';
		var currentNode = this.head;
		while(currentNode.next != null){
			str+=currentNode.next.element;
			currentNode = currentNode.next;
		}
	return str;
	}
}

双向链表的实现
通过给 Node 对象增加一个属性,该属性存储指向前驱节点的链接。此时向链表插入一个节点需要更多的工作,我们需要指出该节点正确的前驱和后继。但是在从链表中删除节点时,效率提高了,不需要再查找待删除节点的前驱节点了。

删除节点: 首先需要在链表中找出存储待删除数据的节点,然后设置该节点前驱的 next 属性,使其指向待删除节点的后继;设置该节点后继的 previous 属性,使其指向待删除节点的前驱。

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

var linkedList = function () {
    this.head = new Node('head');
}

linkedList.prototype = {
    //查找当前节点的父节点
    find: function (item) {
        var currentNode = this.head;
        while (currentNode.element != item) {
            currentNode = currentNode.next;
        }
        return currentNode;
    },
    //返回最后一个节点
    findLast: function () {
        var currentNode = this.head;
        while (currentNode.next != null) {
            currentNode = currentNode.next;
        }
        return currentNode;
    },
    //添加一个元素
    insert: function (element, item) {
        var nowNode = new Node(element);
        var currentNode = this.find(item);        
        nowNode.next = currentNode.next;
        nowNode.previous = currentNode; 
        currentNode.next = nowNode;               
    },
    //删除一个元素
    remove: function (item) {
        var currentNode = this.find(item);
        if (currentNode.next != null) {
            currentNode.next.previous = currentNode.previous;
            currentNode.previous.next = currentNode.next
            currentNode.next = null;
            currentNode.previous = null;
        }
    },
    //展示整个列表
    display: function () {
        var curNode = this.head;
        var curStr = ''
        while (curNode.next != null) {
            curStr += curNode.next.element;
            curNode = curNode.next;
        }
        return curStr;
    },

    //反向展示
    displayReverse: function () {
        var endNode = this.findLast();
        var endStr = '';
        while (endNode.previous != null) {
            endStr += endNode.element;
            endNode = endNode.previous;
        }
        return endStr;
    }
}

循环链表

如果你希望可以从后向前遍历链表,但是又不想付出额外代价来创建一个双向链表,那么
就需要使用循环链表。从循环链表的尾节点向后移动,就等于从后向前遍历链表。
创建循环链表,只需要修改 linkedList 类的原型函数:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值