介绍
要存储多个元素,一般都会选择数组,但是这种数据结构有一个缺点:一般数组的大小都是固定的,从数组的起点或中间插入或移除元素成本有点高。这时候就可以选择链表。
链表存储有序的元素集合,但不同于数组,链表的元素在内存中不是连续放置的,每个元素由一个存储元素本身的节点个指向下一个元素的引用组成。
相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然 而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何 位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到所需的元素。
创建链表
1 function LinkedList() {
2 let Node = function(element){ // Node辅助类,要加入列表的项。element要加入的值,next表示指向列表下一个节点
3 this.element = element;
4 this.next = null;
5 };
6 let length = 0; // 存储列表项数量
7 let head = null; // 存储第一个节点的引用,存到变量head中。
8 this.append = function(element){}; //向列表项尾部添加新的项
9 this.insert = function(position, element){}; //向列表指定位置插入新的项
10 this.removeAt = function(position){}; //从列表特定位置移除一项
11 this.remove = function(element){}; //从列表中移除一项
12 this.indexOf = function(element){}; //返回元素在列表的索引,没有则返回-1
13 this.isEmpty = function() {}; //如果链表中不包含任何元素,返回true,如果链表长度大于0,则返回false
14 this.size = function() {}; //返回链表的长度
15 this.getHead = function(){};
16 this.toString = function(){}; //输入链表元素值
17 this.print = function(){};
18 }
向链表尾部添加元素
两种场景:列表为空,添加的是第一个元素;列表不为空,向其追加元素
1 this.append = function (element) {
2 let node = new Node(element), //传入element值,作为Node项
3 current; //{2}
4 if (head === null) { //列表中第一个节点为空时,此时head指向node
5 head = node;
6 } else {
7 current = head;
8 //循环列表,直到找到最后一项
9 while (current.next) {
10 current = current.next;
11 }
12 //找到最后一项,将其next赋为node,建立链接
13 current.next = node;
14 }
15 length++; //更新列表的长度
16 };
从链表中移除元素
两种场景:移除第一个元素;移除第一个以外的元素。
1 this.removeAt = function (position) {
2 //检查越界值
3 if (position > -1 && position < length) {
4 let current = head,
5 previous,
6 index = 0;
7 //移除第一项
8 if (position === 0) {
9 head = current.next;
10 } else {
11 while (index++ < position) {
12 previous = current;
13 current = current.next;
14 }
15 //将previous与current的下一项链接起来:跳过current,从而移除它
16 previous.next = current.next;
17 }
18 length--;
19 return current.element;
20 } else {
21 return null;
22 }
23 };
在任意位置插入元素
1 this.insert = function (position, element) {
2 //检查越界值
3 if (position >= 0 && position <= length) {
4 let node = new Node(element),
5 current = head,
6 previous,
7 index = 0;
8 if (position === 0) { //在第一个位置添加
9 node.next = current;
10 head = node;
11 } else {
12 while (index++ < position) {
13 previous = current;
14 current = current.next;
15 }
16 node.next = current;
17 previous.next = node;
18 }
19 length++; //更新列表的长度
20 return true;
21 } else {
22 return false;
23 }
24 };
toString方法
1 this.toString = function () {
2 let current = head,
3 string = '';
4 while (current) {
5 string += current.element + (current.next ? 'n' : '');
6 current = current.next;
7 }
8 return string;
9 };
indexOf方
indexOf方法
1 this.indexOf = function (element) {
2 let current = head,
3 index = -1;
4 while (current) {
5 if (element === current.element) {
6 return index;
7 }
8 index++;
9 current = current.next;
10 }
11 return -1;
12 };
isEmpoty方法
1 this.isEmpty = function() {
2 return length === 0;
3 };
size方法
1 this.size = function() {
2 return length;
3 };
getHead方法
1 this.getHead = function(){
2 return head;
3 };