JavaScriptの二分探索木(BST)で最小値と最大値を検索する方法
二分探索木(Binary Search Tree:BST)には「左の子は必ず親より小さい」という重要な性質があります。この性質に注目すると、左の子が存在しなくなるまで左へ辿り続ければ、BST内の最小値のノードにたどり着くことが分かります。
同様に、「右の子は必ず親より大きい」という性質から、右端まで辿れば最大値が見つかることも理解できます。
それでは、実際にコードでこの機能を実装してみましょう。ここからは関数を反復処理版または再帰版のどちらか一方のみ実装していきます。今回は反復処理を使った関数を作成します。
getMinVal() の実装例
getMinVal() {
if (this.root === null) {
throw "Empty tree!";
}
let currNode = this.root;
// 左の子がなくなるまで左へ移動
while (currNode.left !== null) {
currNode = currNode.left;
}
return currNode.data;
}まず、ルートが空の場合は例外をスローしてエラーを通知します。その後、ルートから開始し、left プロパティが null になるまで左の子ノードへ移動を繰り返します。最終的に到達したノードのデータが最小値です。
動作確認
以下のコードでテストできます。
let BST = new BinarySearchTree(); BST.insertRec(10); BST.insertRec(15); BST.insertRec(5); BST.insertRec(50); BST.insertRec(3); BST.insertRec(7); BST.insertRec(12); console.log(BST.getMinVal());
出力結果
3
木の中で最も小さい値である 3 が正しく取得できています。
getMaxVal() の実装
同じ考え方で、最大値を返す getMaxVal() 関数も作成できます。こちらは右端の子ノードまで反復処理することで値を取得します。以下に検証用のコードを示します。
getMaxVal() {
if (this.root === null) {
throw "Empty tree!";
}
let currNode = this.root;
// 右の子がなくなるまで右へ移動
while (currNode.right !== null) {
currNode = currNode.right;
}
return currNode.data;
}計算量について
これらの操作の時間計算量は O(h)(h は木の高さ)です。木がバランスしている場合、O(log n) で高速に動作しますが、偏った木(連結リストのような形)では O(n) になる点に注意しましょう。BSTを扱う上で、挿入時にバランスを保つこと(AVL木や赤黒木などの自己平衡木)が重要な理由の一つです。
-
C++で二分木の最大値(または最小値)を求める方法
この記事では、二分木が与えられたときに、その中から最大値(または最小値)を持つノードを見つける方法を解説します。 問題の概要 与えられた二分木の中から、最大値および最小値を持つノードの値を求めるのが課題です。 入力例 出力例 max = 9 , min = 1 解法のアプローチ 二分木の最大値を求めるには、木全体を走査する必要があります。基本的な考え方は次のとおりです。 ルートノードから出発し、再帰的に左部分木と右部分木を走査します。 各ノードにおいて、そのノードの値・左部分木の最大値・右部分木の最大値を比較します。 最も大きい値を現在の最大値として返し、再帰的に結果を親ノードへ伝えてい
-
C++で解く二分木における最大合計BSTの求め方
問題概要 二分木のルートが与えられたとき、二分探索木(BST)でもある部分木の中から、ノード値の合計が最大となるものを見つけることを考えます。 例えば、次のような入力が与えられた場合を考えてみましょう。 この場合の出力は 20 になります。これは選択されたBSTに含まれるすべてのノードの値の合計です。 解法のアプローチ この問題は、木を後順トラバーサル(子→親の順)で処理し、各ノードを根とする部分木に関する情報をボトムアップに集約することで効率的に解けます。具体的な手順は以下の通りです。 Data という構造体を作成します。sz(部分木のノード数)、maxVal(最大値)、minVal(最