用 JavaScript 實現鏈表操做 - 02 Length & Count

TL;DR

計算鏈表的長度和指定元素的重複次數。系列目錄見 前言和目錄javascript

需求

實現一個 length() 函數來計算鏈表的長度。java

length(null) === 0
length(1 -> 2 -> 3 -> null) === 3

實現一個 count() 函數來計算指定數字在鏈表中的重複次數。node

count(null, 1) === 0
count(1 -> 2 -> 3 -> null, 1) === 1
count(1 -> 1 -> 1 -> 2 -> 2 -> 2 -> 2 -> 3 -> 3 -> null, 2) === 4

length

遞歸版本

遞歸是最有表達力的版本。思路很是簡單。每一個鏈表的長度 length(head) 都等於 1 + length(head.next) 。空鏈表長度爲 0 。git

function length(head) {
  return head ? 1 + length(head.next) : 0
}

循環版本 - while

鏈表循環第一反應是用 while (node) { node = node.next } 來作,循環外維護一個變量,每次自增 1 便可。github

function lengthV2(head) {
  let len = 0
  let node = head

  while (node) {
    len++
    node = node.next
  }

  return len
}

循環版本 - for

forwhile 在任何狀況下都是能夠互換的。咱們能夠用 for 循環把變量初始化,節點後移的操做都放到一塊兒,簡化一下代碼量。注意由於 len 要在 for 外部做爲返回值使用,咱們只能用 var 而不是 let/const 聲明變量。segmentfault

function lengthV3(head) {
  for (var len = 0, node = head; node; node = node.next) len++
  return len
}

count

遞歸版本

length 思路相似,區別只是遞歸時判斷一下節點數據。函數

function count(head, data) {
  if (!head) return 0
  return (head.data === data ? 1 : 0) + count(head.next, data)
}

循環版本

這裏我直接演示的 for 版本,思路相似就很少說了。測試

function countV2(head, data) {
  for (var n = 0, node = head; node; node = node.next) {
    if (node.data === data) n++
  }
  return n
}

參考資料

Codewars Kata
GitHub 的代碼實現
GitHub 的測試code

相關文章
相關標籤/搜索