单向链表的 js 实现
單向鏈表
鏈表是一種數據結構,有單向鏈表、雙向鏈表和循環鏈表,單向鏈表事其中最簡單的一種。它有一個 head 指針,整個鏈表有很多節點構成,而 head 會始終指向鏈表的頭節點;每個節點由兩個信息組成:節點數據和指向下一個節點的指針,最后一個節點的指針為 null 。
節點
單向鏈表是由一個個節點組成的數據結構類型,每個節點都包含該節點的數據和指向下一個節點的指針,構造一個節點很簡單,只需要包含這兩項內容就可以了,用 ES6 的寫法可以這樣描述一個節點:
/*** 單個鏈表節點*/ class Node {constructor(val) {this.val = val;this.next = null;} }鏈表結構
一個鏈表除了由一個個節點之外,還包含一些屬性,如:長度、head指針(用以指向鏈表的第一個節點),這里新建一個類作如下描述:
/*** 鏈表*/ class LinkedList {constructor(val = null) {this.head = null; // 鏈表的head指針this.length = 0; // 鏈表的長度if (val) {this.head = new Node(val);this.length = 1;}} }這樣這個鏈表結構就有了額外的長度、head指針信息,我們可以構造一個實例看看:
添加一些方法
一般鏈表都會包含一些操作方法,比如 append、remove...下面就來來添加這些操作函數。
append(在鏈表尾部添加一個節點)
這里的重點是如何找到鏈表尾部,這里使用循環整個鏈表,找到一個節點,它的 next 指向為空即可:
class LinkedList {...append(val) {const node = new Node(val); // 創建節點if (this.head === null) { // 如果是個空列表this.head = node;} else {let current = this.head;while (current.next) { // 找到 next 指向為空的節點current = current.next;}current.next = node;}this.length += 1; // 整個鏈表的長度增加}... }removeAt(刪除指定位置的節點)
從一個鏈表刪除某節點,只需要將該節點前一個的 next 指向替換為該節點的 next 指向即可,這樣從整個鏈表來看就跳過了該節點,需要注意的是需要對用戶的輸入進行判斷:
class LinkedList {...removeAt(position) {if (position >= this.length || position < 0) { // 判斷輸入return null;}let current = this.head;if (position === 0) { // 刪除頭節點,只需改變 head 指針即可this.head = current.next;} else {let index = 0;let prev = null;while (index < position) {prev = current;current = current.next;index += 1;}prev.next = current.next; // 改變上一個節點的 next 指向}this.length -= 1; // 長度減少return current.val; // 返回刪除節點的值}... }insert(在指定位置插入節點)
跟前面的尾部插入不同,這里需要找到插入的位置,再執行插入操作:
class LinkedList {...insert(position, val) {if (position >= this.length || position < 0) {return false;}const node = new Node(val);if (position === 0) { // 插入位置在頭節點node.next = this.head;this.head = node;} else {let index = 0;let current = this.head;let prev = null;while (index < position) { // 遍歷鏈表找到指定位置的節點,并記錄下前一個節點和該位置原節點prev = current;current = current.next;index += 1;}node.next = current;prev.next = node;}this.length += 1;return true;}... }這里可以看到關鍵的兩步是:把插入位置的前一個節點的 next 指向待插入的節點;把待插入的節點的 next 指向原來在該位置上的節點。
indexOf(返回第一個指定值的節點的位置)
這個功能也比較簡單,只需要從第一個節點開始遍歷,直到找到值符合要求的節點位置即可,在這里加入了一個可以設置起始位置的功能,無非是多了一個判斷:
class LinkedList {...indexOf(val, start = 0) {if (start >= this.length) { // 判斷起始位置是否合法return -1;}let index = 0;let current = this.head;while (index < this.length) {if (current.val === val && index >= start) {return index;}current = current.next;index += 1;}return -1;}... }remove(移除第一個指定值的節點)
這個功能可以結合上面的 indexOf 和 removeAt 來完成:
class LinkedList {...remove(val, start = 0) {const index = this.indexOf(val, start);return this.removeAt(index);}... }size(返回鏈表長度)
class LinkedList {...size() {return this.length;}... }isEmpty(返回是否為空鏈表)
class LinkedList {...isEmpty() {return !!this.length;}... }添加了這些方法之后,就是一個完整的單向鏈表 js 實現了。
總結
以上是生活随笔為你收集整理的单向链表的 js 实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 裸奔mysql
- 下一篇: JSsearch实现在购物网站输入后推荐