链表优缺点
对于数组来说,链表的优缺点:
数组的缺点
- 数组的插入和移除是需要比较大成本的,因为每次操作,都需要移动大量的元素
- 数组是需要指定一块相对大小的内存
数组的优点
- 可以很方便的取出某一个位置的值,适合用于检索数据
链表的缺点
- 每次寻找数据都要遍历所有的节点,不适用与检索数据,适合存储数据
链表的优点
- 链表存储数据只要修改引用地址,其成本减少很多。
- 链表不需要指定内存大小,相对灵活,适合存储数据
这其中的链表又分为单向链表和双向链表。其各自的缺点如下:
单向链表的缺点
可以到达下一个节点,但是回到上一个节点很难,需要重新遍历
双向链表的缺点
- 每次插入或者删除,需要处理四个节点的引用
- 占用的内存空间更大
综上比较
- 数组适合用于检索数据的场景
- 链表适用于存储数据的场景
- 单向链表占用的内存空间比较小,但是回到上一个节点,比较难
- 双向链表占用的空间比较大,每次插入删除,需要考虑四种场景,较复杂,但是回到上一个节点比较简单。
单向链表的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| function SingleLinked(){ function Node(element){ this.element = element; this.next = null; } this.head = null; this.length = 0; SingleLinked.prototype.append = function(element){ var current = this.head; var newNode = new Node(element); if(this.head === null) { this.head = newNode; }else { while(current.next){ current = current.next; } current.next = newNode; } this.length ++; } SingleLinked.prototype.insert = function (position,element) { if(position < 0 || position > this.length )return false; var newNode = new Node(element); var current = this.head; var prev = null; if(position === 0){ newNode.next = this.head; this.head = newNode; }else{ var index = 0; while(index < position ){ prev = current; current = current.next; index++; } prev.next = newNode; newNode.next = current; } this.length++; return true; } SingleLinked.prototype.toString = function(){ var str = ''; var current = this.head; while(current){ str += ','+current.element; current = current.next; } return str.slice(1); } SigleLinked.prototype.removeAt = function(position){ if(position < 0 || position > this.length || this.head === null )return null; var current = this.head; var prev = null; if(position === 0){ if(this.length === 1){ this.head = null; }else{ this.head = this.head.next; } }else { var index = 0; while(index < position){ prev = current; current = current.next; index ++; } prev.next = current.next; } this.length -- ; return current.element; } SingleLinked.prototype.indexOf = function(element){ var current = this.head; var index = 0; while(current){ if(current.element === element){ return index; } current = current.next; index ++; } return -1; } SingleLinked.prototype.remove = function(element){ var index = this.indexOf(element); return this.removeAt(index) } SingleLinked.prototype.isEmpty = function(){ return this.length === 0; } SingleLinked.prototype.firstNode = function(){ return this.head.element; } }
var lk = new Linked() lk.append(1) lk.append(2) lk.append(3) lk.append(4) lk.append(5) lk.append(6) lk.append(7) lk.append(8) alert(lk)
|
双向链表的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| function DoubleLinkNode(){ function Node(element){ this.element = element; this.next = null; this.prev = null; } this.length = 0; this.head = null; this.tail = null; DoubleLinkNode.prototype.append = function(element){ var newNode = new Node(element); if(this.head == null){ this.head = newNode; this.tail = newNode; }else{ this.tail.next = newNode; newNode.prev = this.tail; this.tail = newNode; } this.length ++ ; } DoubleLinkNode.prototype.forwardSting = function(){ var current = this.head; var str = ''; while(current){ str += ','+current.element; current = current.next; } return str.slice(1); } DoubleLinkNode.prototype.backwardString = function(){ var current = this.tail; var str = ''; while(current){ str += ','+current.element; current = current.prev; } return str.slice(1); } DoubleLinkNode.prototype.insert = function(position,element){ var newNode = new Node(element); if(position<0||position>this.length)return false; var newNode = new Node(element); var current = this.head; if(position === 0){ if(this.head === null){ this.head = newNode; this.tail = newNode; }else{ this.head.prev = newNode; newNode.next = this.head; this.head = newNode; } }else if(position === this.length){ this.tail.next = newNode; newNode.prev = this.tail; this.tail = newNode; }else{ var index = 0; while(index < position){ prev = current; current = current.next; index++; } current.prev = newNode; prev.next = newNode; newNode.next = current; newNode.prv = prev; } this.length ++; return true; } DoubleLinkNode.prototype.removeAt = function(position){ if(position < 0 || position >= this.length) return false; var current = this.head; if (position === 0) { if (this.length === 1) { this.head = null; this.tail = null; }else { this.head = current.next; this.head.prev = null; } }else if (position === this.length - 1) { current = this.tail; this.tail = current.prev; this.tail.next = null; }else{ var index = 0; while (index < position){ prev = current; current = current.next; index++; } prev.next = current.next; current.next.prev = prev; } this.length --; } DoubleLinkNode.prototype.indexOf = function(element){ current = this.head; var index = 0; while(current){ if(element === current.element){ return index; } current = current.next index ++ ; } return -1; } DoubleLinkNode.prototype.remove = function(element) { var index = this.indexOf(element) return this.removeAt(index); } DoubleLinkNode.prototype.empty = function(){ return this.length === 0; } DoubleLinkNode.prototype.firstNode = function(){ return this.head.element; } DoubleLinkNode.prototype.lastNode = function(){ return this.tail.element; } } var d = new DoubleLinkNode(); d.append(1); d.append(2); d.append(3); d.append(4); d.append(5); d.append('a') d.removeAt(0); alert(d.length) d.removeAt(3); alert(d.length) alert(d.backwardString()); alert(d.forwardSting()) alert('a的前置位置在'+d.indexOf('a'))
|