JavaScript数据结构——链表
Posted Ruth92
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript数据结构——链表相关的知识,希望对你有一定的参考价值。
链表:存储有序的元素集合,但不同于数组,链表中的元素在内存中不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。
好处:可以添加或移除任意项,它会按需扩容,且不需要移动其他元素。
与数组的区别:
数组:可以直接访问任何位置的任何元素;
链表:想要访问链表中的一个元素,需要从起点(表头)开始迭代列表直到找到所需的元素。
现实案例:康佳舞队、寻宝游戏
单向链表:一个节点只有链向下一个节点的链接;
双向链表:链接是双向的,一个链向下一个元素,另一个链向前一个元素
优点:双向链表提供了两种迭代列表的方法:从头到尾,或者反过来。我们也可以访问一个特定节点的下一个或前一个元素。在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表起点,重新开始迭代。
-------------------------------------------------------------------------------------------------------------
链表方法声明:
1. 定义Node辅助类;
2. 内部属性 length;
2. 存储第一个节点(head)的引用
序号
|
方法
|
说明
|
1
|
append(element) | 向列表尾部添加一个新的项 |
2
|
insert(position, element) | 向列表的特定位置插入一个新的项 |
3
|
remove(element)
|
从列表中移除一项 |
4
|
indexOf (element )
|
返回元素在列表中的索引。如果列表中没有该元素则返回-1 |
5
|
removeAt(position) |
从列表的特定位置移除一项
|
6
|
isEmpty()
|
如果链表中不包含任何元素,返回 true,如果链表长度大于 0 则返回 false
|
7
|
size ( )
|
返回链表包含元素个数。与数组的 length 属性类似 |
8
|
toString ( )
|
由于列表项使用了 Node 类,就需要重写继承自 javascript 对象默认的 toString 方法,让其只输出元素的值 |
链表实现:
1 function LinkedList() { 2 // 定义辅助类Node 3 var Node = function(element) { 4 this.element = element; // element属性,即要添加到列表的元素 5 this.next = null; // next属性,即指向列表中下一个节点项的指针 6 } 7 8 var length = 0; // 内部属性/私有变量 9 var head = null; // 第一个节点的引用 10 11 // 方法 12 this.append = function(element) { 13 var node = new Node(element), // 把element作为值传入,创建Node项 14 current; 15 16 if (head === null) { // 列表中第一个节点,如果head元素为null,则意味着向列表添加第一个元素 17 head = node; // head指向node元素,下一个node将会自动生成null 18 } else { 19 current = head; 20 21 // 循环列表,直到找到最后一项 22 while(current.next) { 23 current = current.next; 24 } 25 26 // 找到最后一项,将其next赋为node,建立连接 27 current.next = node; // 列表中最后一个节点的下一个元素始终是null 28 } 29 30 length++; // 更新链表长度,这样就能控制它,轻松地得到列表的长度 31 }; 32 33 this.insert = function(position, element) { 34 // 检查越界值 35 if (position >= 0 && position <= length) { 36 var node = new Node(element), 37 current = head, 38 previous, 39 index = 0; 40 41 if (position === 0) { // 在第一个位置添加 42 node.next = current; 43 head = node; 44 } else { 45 while (index++ < position) { 46 previous = current; 47 current = current.next; 48 } 49 node.next = current; 50 previous.next = node; 51 } 52 53 length++; 54 55 return true; 56 57 } else { 58 return false; 59 } 60 }; 61 62 this.removeAt = function(position) { 63 // 检查越界值 64 if (position > -1 && position < length) { 65 var current = head, // current变量总是为对所循环列表的当前元素的引用 66 previous, // previous变量为对当前元素的前一个元素的引用 67 index = 0; 68 69 // 移除第一项 70 if (position === 0) { 71 head = current.next; 72 } else { 73 while (index++ < position) { // 使用用于内部控制和递增的index变量来迭代列表 74 previous = current; 75 current = current.next; 76 } 77 78 // 将previous与current的下一项链接起来:跳过current,从而移除它 79 previous.next = current.next; 80 } 81 82 length--; 83 84 return current.element; 85 } else { 86 return null; 87 } 88 }; 89 90 this.remove = function(element) { 91 var index = this.indexOf(element); 92 return this.removeAt(index); 93 }; 94 95 this.indexOf = function(element) { 96 var current = head, 97 index = -1; 98 99 while (current) { 100 if (element === current.element) { 101 return index; 102 } 103 index++; 104 current = current.next; 105 } 106 107 return -1; 108 }; 109 110 this.isEmpty = function() { 111 return length === 0; 112 }; 113 114 this.size = function() { 115 return length; 116 }; 117 118 this.toString = function() { 119 var current = head, 120 string = ‘‘; 121 122 while (current) { 123 string += current.element; 124 current = current.next; 125 } 126 127 return string; 128 }; 129 130 this.getHead = function () { 131 return head; 132 }; 133 }
双向链表实现:
1 function DoublyLinkedList() { 2 var Node = function(element) { 3 this.element = element; 4 this.next = null; 5 this.prev = null; 6 }; 7 8 var length = 0; 9 var head = null; 10 var tail = null; // 新增的 11 12 // 方法 13 this.insert = function(position, element) { 14 // 检查越界值 15 if (position >= 0 && position <= length) { 16 var node = new Node(element), 17 current = head, 18 previous, 19 index = 0; 20 21 if (position === 0) { // 在第一个位置添加 22 if (!head) { // 新增的 23 head = node; 24 tail = node; 25 } else { 26 node.next = current; 27 current.prev = node; 28 head = node; 29 } 30 } else if (position === length-1) { // 最后一项 //新增的 31 current = tail; 32 current.next = node; 33 node.prev = current; 34 tail = node; 35 } else { 36 while (index++ < position) { 37 previous = current; 38 previous.next = node; 39 } 40 41 node.next = current; 42 previous.next = node; 43 44 current.prev = node; //新增的 45 node.prev = previous; //新增的 46 } 47 48 length++; 49 return true; 50 51 } else { 52 return false; 53 } 54 }; 55 56 this.removeAt = function(position) { 57 // 检查越界值 58 if (position > -1 && position < length) { 59 var current = head, 60 previous, 61 index = 0; 62 63 // 移除第一项 64 if (position === 0) { 65 head = current.next; 66 67 // 如果只有一项,更新tail //新增的 68 if (length === 1) { 69 tail = null; 70 } else { 71 head.prev = null; 72 } 73 } else if (position === length-1) { 74 current = tail; 75 tail = current.prev; 76 tail.next = null; 77 } else { 78 while (index++ < position) { 79 previous = current; 80 current = current.next; 81 } 82 // 将prvious与current的下一项链接起来——跳过current 83 previous.next = current.next; 84 current.next.prev = previous; // 新增的 85 } 86 87 length--; 88 89 return current.element; 90 } else { 91 return null; 92 } 93 }; 94 }
以上是关于JavaScript数据结构——链表的主要内容,如果未能解决你的问题,请参考以下文章