C++で二分木における最も近い葉ノードまでの距離を求める方法
二分木が与えられ、その葉ノードはそれぞれ異なるレベルに存在するとします。さらに、あるノードを指すポインタが与えられ、そのノードから最も近い葉ノードまでの距離を求める必要があります。
例として、次のような二分木を考えてみましょう。

この木における葉ノードは 2、-2、6 の3つです。もしポインタがノード -5 を指している場合、-5 から最も近い葉ノードまでの距離は 1 となります。
解決のアプローチ
この問題を解くには、次の手順で考えます。
まず、指定されたノードを根とする部分木を走査し、その部分木内で最も近い葉ノードを見つけて距離を記録します。次に、木の根から全体を走査します。ノード x が左部分木に存在する場合は右部分木側の葉を探索し、逆に右部分木に存在する場合は左部分木側の葉を探索します。これにより、指定ノードの祖先を経由して到達できる葉ノードも考慮した最小距離が求められます。
C++による実装例
#include<iostream>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
};
Node* getNode(int data) {
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return node;
}
void getLeafDownward(Node *root, int level, int *minDist) {
if (root == NULL)
return ;
if (root->left == NULL && root->right == NULL) {
if (level < (*minDist))
*minDist = level;
return;
}
getLeafDownward(root->left, level+1, minDist);
getLeafDownward(root->right, level+1, minDist);
}
int getFromParent(Node * root, Node *x, int *minDist) {
if (root == NULL)
return -1;
if (root == x)
return 0;
int l = getFromParent(root->left, x, minDist);
if (l != -1) {
getLeafDownward(root->right, l+2, minDist);
return l+1;
}
int r = getFromParent(root->right, x, minDist);
if (r != -1) {
getLeafDownward(root->left, r+2, minDist);
return r+1;
}
return -1;
}
int minimumDistance(Node *root, Node *x) {
int minDist = INT8_MAX;
getLeafDownward(x, 0, &minDist);
getFromParent(root, x, &minDist);
return minDist;
}
int main() {
Node* root = getNode(4);
root->left = getNode(2);
root->right = getNode(-5);
root->right->left = getNode(-2);
root->right->right = getNode(6);
Node *x = root->right;
cout << "Closest distance of leaf from " << x->data <<" is: " << minimumDistance(root, x);
}実行結果
Closest distance of leaf from -5 is: 1
コードの解説
この実装では、主に3つの関数が連携して動作します。
getLeafDownward は、指定されたノードから下方向へ再帰的に走査し、葉ノードに到達した時点での深さ(レベル)が現在の最小距離より小さければ更新します。
getFromParent は、根から目的のノード x を探索します。x が見つかった位置から遡りながら、その兄弟部分木に含まれる葉ノードまでの距離を計算し、最小距離の候補として記録します。
minimumDistance は、まず指定ノード自身の部分木内の最短距離を求め、次に祖先経由で到達できる葉ノードの距離も考慮することで、最終的な最小距離を返します。
このアルゴリズムにより、指定されたノードから最も近い葉ノードまでの距離を効率的に求めることができます。
-
C++の二分探索木(BST)で最小値のノードを見つける方法
二分探索木(Binary Search Tree、BST)が与えられたとき、その木の中から最小の要素を見つけることを考えます。例えば、以下のようなBSTがあるとします。この場合、最小要素は 1 になります。考え方二分探索木の重要な性質として、左部分木には必ず親ノードより小さい値が格納されるというものがあります。この性質を利用すると、次の手順で最小要素を見つけることができます。ルートノードから探索を開始します。現在のノードの左の子が NULL でない間、左の子へ移動を繰り返します。左の子が NULL になったノードの値が、木全体の中で最小の要素です。この操作の計算量は木の高さに依存し、平衡な二分
-
C++で二分木のノードを葉ノードになった順に出力する方法
問題概要 二分木が与えられたとき、まずその葉ノード(リーフノード)を出力します。次に、出力した葉ノードを木から取り除き、新たに葉ノードとなったノードを出力します。この操作を、木の中にノードが一つも残らなくなるまで繰り返します。 例 以下のような二分木を例に考えてみましょう。 まず最下層の葉ノード「6 7 9 13 14」を出力して取り除き、次に新たな葉ノードとなった「3 4」を出力、続いて「2」、最後に根ノード「1」を出力します。したがって、この問題の出力は以下のようになります。 6 7 9 13 14 3 4 2 1 アプローチ この問題では、DFS(深さ優先探索)を用いたアプロ