JavaScriptでチェーン操作を実現する-10 Move Node In-place
2686 ワード
TL;DR
一つのチェーンの最初のノードを別のチェーンに移動します.(チェーンの参照を変えません.)シリーズのディレクトリは前書きとディレクトリに会います.
需要
一つのソースチェーンは です.ターゲットチェーンは です.ソース・チェーンは空のノードであり、 前のkataとは違って、このkataは引用を変えずに2つのチェーン自体を修正しました.したがって、
最初のkataの
最良の案
このアルゴリズムは、リンクノードの挿入と削除を考える.基本的にはsourceとdestだけを一回ずつ操作しますので、再帰と循環を区別する必要はありません.大体の考えは次の通りですは、 は、 コードは以下の通りです
これは私が最初に考えたスキームであり、違いは
コードは以下の通りです.主に
再帰性を常に使用すると慣性が発生し、データ構造の基本特性を無視する結果となる.チェーンの特性は挿入と削除の便利さです.引用を変更すればいいです.
アルゴリズムに関するコードとテストは全部GitHubに置いています.もしあなたに助けがあれば、いい評価をお願いします.
参考資料
Codewars Kata GitHubのコードはGitHubのテストを実現します.
一つのチェーンの最初のノードを別のチェーンに移動します.(チェーンの参照を変えません.)シリーズのディレクトリは前書きとディレクトリに会います.
需要
一つの
moveNode()
関数を実現して、ソースチェーンの頭の接合点をターゲットチェーンの先頭に移動します.二つのチェーンの参照は修正できないことが要求されます.var source = 1 -> 2 -> 3 -> null
var dest = 4 -> 5 -> 6 -> null
moveNode(source, dest)
source === 2 -> 3 -> null
dest === 1 -> 4 -> 5 -> 6 -> null
以下の場合は異常を投げ出すべきです.null
null
data
属性がnull
のノードは空のノードとして定義されている.moveNode()
関数は、戻り値を必要としない.また、このkataは空ノードの概念も提案している.空ノードは、ターゲットチェーンが空の場合(参照を保持するため)に使用され、関数が実行されると、ターゲットチェーンは空ノードから一つのノードを含むチェーンテーブルに変化します.最初のkataの
push
メソッドを使用することができます.最良の案
このアルゴリズムは、リンクノードの挿入と削除を考える.基本的にはsourceとdestだけを一回ずつ操作しますので、再帰と循環を区別する必要はありません.大体の考えは次の通りです
source
に対して、ノードを削除する動作を行う.ノードが一つしかないなら、そのまま空にします.複数のノードがある場合は、第2のノードの値をヘッドノードに割り当て、その後、第3のノードをノードの先頭にノードを指す.dest
にノードを挿入する動作をする.頭の結点が空なら直接に値を付けます.そうでないと、頭の結点をコピーして、第二のノードとしてチェーンに挿入して、新しい値を頭の結点に割り当てます.function moveNode(source, dest) {
if (!source || !dest || source.data === null) throw new Error("invalid arguments")
const data = source.data
if (source.next) {
source.data = source.next.data
source.next = source.next.next
} else {
source.data = null
}
if (dest.data === null) {
dest.data = data
} else {
dest.next = new Node(dest.data, dest.next)
dest.data = data
}
}
再帰案これは私が最初に考えたスキームであり、違いは
dest
にどのように新しいノードを挿入する処理に再帰的に使用されたかである.考え方は、すべてのノードのdata
を後に1つ移動し、すなわち、新しい値を第1のノードに割り当て、第1のノードの値を第2のノードに与え、第2のノードの値を第3のノードに割り当て、これに類する.しかし、実際の動作の順序は逆でなければならない.最後のノードに最後のノードの値を与え、最後の3番目のノードの値を最後の2番目のノードに与えている.しかし、面白い再帰的な用例として、私はそれを上に置いてきました.コードは以下の通りです.主に
dest
を見ます.function moveNodeV2(source, dest) {
if (source === null || dest === null || source.isEmpty()) {
throw new Error('invalid arguments')
}
pushInPlaceV2(dest, source.data)
if (source.next) {
source.data = source.next.data
source.next = source.next.next
} else {
source.data = null
}
}
function pushInPlaceV2(head, data) {
if (!head) return new Node(data)
if (!head.isEmpty()) head.next = pushInPlaceV2(head.next, head.data)
head.data = data
return head
}
締め括りをつける再帰性を常に使用すると慣性が発生し、データ構造の基本特性を無視する結果となる.チェーンの特性は挿入と削除の便利さです.引用を変更すればいいです.
アルゴリズムに関するコードとテストは全部GitHubに置いています.もしあなたに助けがあれば、いい評価をお願いします.
参考資料
Codewars Kata GitHubのコードはGitHubのテストを実現します.