前面讲解了数组,栈和队列。其实大家回想一下。它们有很多相似的地方。甚至栈和队列这两种数据结构在js中的实现方式也都是基于数组。无论增删的方式、遵循的原则如何,它们都是有序集合的列表。在js中,我们新建一个数组并不需要限定他的大小也就是长度,但是实际上,数组的底层仍旧为初始化的数组设置了一个长度限制。我们想要在数组中任意的插入和删除元素的成本很高,虽然在js中我们有便捷的方法可以操作数组,但是其底层原理仍旧是这样的。只是我们对它并没有感觉,比如在java中,声明一个数组是必须要限制它的长度的。并且在扩容的情况下,操作起来也不是十分方便。这就需要用到其它的数据结构来应对我们不同的需要,比如链表。
链表存储有序的元素的集合,但是和数组不同的是,链表中的元素在内存中的存储并不是连续的。每一个链表元素都包含了一个存储元素本身的节点和一个指向下一个元素的引用。看起来就像这样:
相对于传统的数组,链表的一个好处就是增删的时候无需移动其它元素,只要更改指针的指向就可以了。但是缺点就是如果想要访问链表中的元素,需要从头开始循环迭代到你想要的元素。
那么简单介绍了什么是链表之后,我们看看如何用js来实现链表,同样的链表有其自身的几种方法。
1、append(element),向列表尾部添加一个新的元素,注意这里所指的列表并不是我们想象中的有序列表,链表是无序的。
2、insert(position,element),在链表的指定位置插入一个新的元素。
3、remove(element),从列表中移除一项。
4、indexOf(element),返回该元素在列表中的索引,如果列表中没有该元素就返回-1。
5、removeAt(position),从列表的指定位置移除元素。
6、isEmpty(),判断该链表是否为空
7、size(),返回该链表包含的元素个数。
8、toString(),返回链表元素的字符串值。
以上描述了链表包含的各种方法,其实说到底也就是增删改查,任何的数据结构的方法种类也就几乎如此。下面我们来看下具体的实现。
function LinkedList(){ let Node = function (element) { this.element = element; this.next = null; } let length = 0; let head = null; this.append = function (element) {}; this.insert = function (position,element){}; this.removeAt = function (position) {}; this.remove = function (element) {}; this.indexOf = function (element) {}; this.isEmpty = function () {}; this.size = function () {}; this.getHead = function () {}; this.toString = function () {}; this.print = function () {}; }