問題 #6 ・ 木構造・グラフ ・ 難易度 3
次のプログラムは、二分探索木において、値が low 以上 high 以下であるノードの個数を返す関数 countInRange である。二分探索木の性質を利用して不要な部分木の探索を省略している。プログラム中の〔 a 〕に入れる正しい答えを、選択肢の中から選べ。 ここで、二分探索木の各ノードは次の構造をもつ。 Node型: 整数型: value // ノードの値 Node型: left // 左の子(存在しない場合は null) Node型: right // 右の子(存在しない場合は null) また、二分探索木は次の性質をもつ。 ・あるノードの左部分木に含まれるすべてのノードの値は、そのノードの値より小さい。 ・あるノードの右部分木に含まれるすべてのノードの値は、そのノードの値より大きい。 〔プログラムの動作確認用の木の例〕 20 / \ 10 30 / \ / \ 5 15 25 35 この木に対して countInRange(root, 12, 28) を呼び出すと、範囲 12 以上 28 以下に含まれるノード(15, 20, 25)の個数である 3 を返す。
○整数型: countInRange(Node型: node, 整数型: low, 整数型: high)if (node = null)return 0endif整数型: count ← 0if (node.value ≧ low and node.value ≦ high)count ← 1endifif (node.value > low)count ← count + countInRange(node.left, low, high)endifif (〔 a 〕)count ← count + countInRange(node.right, low, high)endifreturn count
二分探索木では、あるノードの右部分木にはそのノードの値より大きい値だけが格納される。したがって、右部分木を探索すべきかどうかは「右部分木に high 以下の値が存在しうるか」で判断する。 node.value < high のとき、右部分木の値は node.value より大きいが high 以下の値が含まれる可能性があるため、探索が必要である。一方、node.value ≧ high のとき、右部分木の全ノードは node.value より大きい、すなわち high より大きいので探索は不要である。 【トレース: countInRange(root, 12, 28)、空欄に node.value < high を入れた場合】 (1) node=20: 20≧12 and 20≦28 → count=1 20>12 → 左探索する、20<28 → 右探索する (2) 左: node=10: 10≧12? No → count=0 10>12? No → 左探索しない(5は範囲外なので正しい枝刈り) 10<28? Yes → 右探索する (3) 左の右: node=15: 15≧12 and 15≦28 → count=1 15>12 → 左:null→0、15<28 → 右:null→0 → return 1 node=10 の count = 0+1 = 1 → return 1 (4) 右: node=30: 30≧12 and 30≦28? No → count=0 30>12 → 左探索する、30<28? No → 右探索しない(35は範囲外なので正しい枝刈り) (5) 右の左: node=25: 25≧12 and 25≦28 → count=1 25>12 → 左:null→0、25<28 → 右:null→0 → return 1 node=30 の count = 0+1 = 1 → return 1 (6) node=20 の count = 1+1+1 = 3 → return 3 範囲内のノード 15, 20, 25 の3個が正しく数えられた。
登録すると解いた結果が残り、間違えた問題は日をおいて復習に出ます。
この問題は AI が作り、別の AI に解かせて検証し、人が確認したうえで公開しています。 誤りに気づいたら goku.tore9@gmail.com までお知らせください。
記号の意味に迷ったら擬似言語の記法で確かめられます。