這篇文章帶給大家的內容是關於JavaScript中鍊錶的詳細介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
鍊錶與陣列
大家都用過js中的陣列,陣列其實是線性表的順序儲存結構,它的特色就是用一組位址連續的儲存單元依序儲存資料元素。而它的缺點也正是其特點而造成,例如對陣列做刪除或插入的時候,可能需要移動大量的元素。
這裡大致模擬一下陣列的插入操作:
insert(arr, index, data){ for(let i = index + 1; i <p>從上面的程式碼可以看出陣列的插入以及刪除都有可能會是一個O(n)的運算。從而引出了鍊錶這種資料結構,鍊錶不要求邏輯上相鄰的元素在物理位置上也相鄰,因此它沒有順序存儲結構所具有的缺點,當然它也失去了數組在一塊連續空間內隨機訪問的優點。 </p><h3>單向鍊錶</h3><p><span class="img-wrap"><img src="https://img.php.cn//upload/image/880/877/695/1546394138978971.png" title="1546394138978971.png" alt="JavaScript中鍊錶的詳細介紹"></span></p><h4>#單向鍊錶的特點:</h4>
用一群組任意的記憶體空間去儲存資料元素(這裡的記憶體空間可以是連續的,也可以是不連續的)
每個節點(node)都由資料本身和一個指向後續節點的指標組成
整個鍊錶的存取必須從頭指標開始,頭指標指向第一個節點
class Node { constructor(key) { this.next = null; this.key = key; } }
##
class List { constructor() { this.head = null; } }
static createNode(key) { return new createNode(key); }
insert(node) { // 如果head有指向的节点 if(this.head){ node.next = this.head; }else { node.next = null; } this.head = node; }
find(key) { let node = this.head; while(node !== null && node.key !== key){ node = node.next; } return node; }
將prevNode中的指標指向NULL
##在清單中間刪除某個節點
尋找到所要刪除節點的上一個節點(prevNode)
delete(node) { // 第一种情况 if(node === this.head){ this.head = node.next; return; } // 查找所要删除节点的上一个节点 let prevNode = this.head; while (prevNode.next !== node) { prevNode = prevNode.next; } // 第二种情况 if(node.next === null) { prevNode.next = null; } // 第三种情况 if(node.next) { prevNode.next = node.next; } }
單向鍊錶整體的程式碼
class ListNode { constructor(key) { this.next = null; this.key = key; } } class List { constructor() { this.head = null; this.length = 0; } static createNode(key) { return new ListNode(key); } // 往头部插入数据 insert(node) { // 如果head后面有指向的节点 if (this.head) { node.next = this.head; } else { node.next = null; } this.head = node; this.length++; } find(key) { let node = this.head; while (node !== null && node.key !== key) { node = node.next; } return node; } delete(node) { if (this.length === 0) { throw 'node is undefined'; } if (node === this.head) { this.head = node.next; this.length--; return; } let prevNode = this.head; while (prevNode.next !== node) { prevNode = prevNode.next; } if (node.next === null) { prevNode.next = null; } if (node.next) { prevNode.next = node.next; } this.length--; } }
從上面的圖可以很清楚的看到雙向鍊錶和單向鍊錶的差異。雙向鍊錶多了一個指向上一個節點的指標。 初始化節點
指向前一個節點的指標指向后一个节点的指针
节点数据
class ListNode { this.prev = null; this.next = null; this.key = key; }
头指针指向NULL
class List { constructor(){ this.head = null; } }
static createNode(key){ return new ListNode(key); }
看上图中head后面的第一个节点可以知道,该节点的prev指向NULL
节点的next指针指向后一个节点, 也就是当前头指针所指向的那个节点
如果head后有节点,那么原本head后的节点的prev指向新插入的这个节点(因为是双向的嘛)
最后将head指向新的节点
insert(node) { node.prev = null; node.next = this.head; if(this.head){ this.head.prev = node; } this.head = node; }
这里和单向节点一样,就直接贴代码了
search(key) { let node = this.head; while (node !== null && node.key !== key) { node = node.next; } return node; }
和之前单向链表一样,分三种情况去看:
删除的是第一个节点
head指向所要删除节点的下一个节点
下一个节点的prev指针指向所要删除节点的上一个节点
删除的是中间的某个节点
所要删除的前一个节点的next指向所要删除的下一个节点
所要删除的下一个节点的prev指向所要删除的前一个节点
删除的是最后一个节点
要删除的节点的上一个节点的next指向null(也就是指向删除节点的next所指的地址)
delete(node) { const {prev,next} = node; delete node.prev; delete node.next; if(node === this.head){ this.head = next; } if(next){ next.prev = prev; } if(prev){ prev.next = next; } }
class ListNode { constructor(key) { // 指向前一个节点 this.prev = null; // 指向后一个节点 this.next = null; // 节点的数据(或者用于查找的键) this.key = key; } } /** * 双向链表 */ class List { constructor() { this.head = null; } static createNode(key) { return new ListNode(key); } insert(node) { node.prev = null; node.next = this.head; if (this.head) { this.head.prev = node; } this.head = node; } search(key) { let node = this.head; while (node !== null && node.key !== key) { node = node.next; } return node; } delete(node) { const { prev, next } = node; delete node.prev; delete node.next; if (node === this.head) { this.head = next; } if (prev) { prev.next = next; } if (next) { next.prev = prev; } } }
这里做一个小总结吧,可能有一部分人读到这里还不是特别的明白,我的建议是先好好看懂上面的单向链表。 其实只要你明白了链表的基础概念,就是有一个head,然后在有好多的节点(Node),然后用一个指针把他们串起来就好了,至于里面的插入操作也好,删除也好,其实都是在调整节点中指针的指向。
以上是JavaScript中鍊錶的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!