C++で二分木が対称(鏡像)かどうかを判定する方法
二分木が与えられ、それが自分自身の鏡像(対称)になっているかどうかを判定する問題を考えてみましょう。対称二分木とは、木全体が自身の鏡像と一致するような二分木のことです。
具体例
例1
入力:

出力:
True
説明:
与えられた二分木は自身の鏡像と一致しているため、出力は True になります。
例2
入力:

出力:
False
説明:
与えられた二分木は鏡像になっていないため、対称な木ではありません。
この問題の解き方
対称な二分木とは、自分自身の鏡像となっている木のことです。つまり、木の左側の部分木と右側の部分木が互いに鏡像の関係にあるかどうかを確認すればよいことになります。
具体的には、ブール型の関数で最初に左のノードと右のノードをチェックします。両方のノードが空(NULL)であれば True を返します。それ以外の場合は、左右の子が存在するときに値が一致していなければならず、これが成り立つときのみ木は対称であると判断できます。
- ルートとその子を含む二分木を用意します。
- ブール型のヘルパー関数
helper(node* root1, node* root2)は、同じ木の2つのノードを受け取り、左の子と右の子が一致しているかどうかの判定を補助します。 - 木が空または NULL の場合は True を返します。
- 再帰的に、左側のノードと右側のノードが等しいかどうかを調べます。このとき、片方の左の子ともう片方の右の子を比較するのがポイントです。
- 上記のいずれの条件も満たさない場合は False を返します。
C++での実装例
#include<bits/stdc++.h>
using namespace std;
struct treenode {
int data;
treenode * left;
treenode * right;
};
struct treenode * createNode(int d) {
struct treenode * root = new treenode;
root -> data = d;
root -> left = NULL;
root -> right = NULL;
return root;
}
bool helper(struct treenode * root1, struct treenode * root2) {
if (root1 == NULL and root2 == NULL)
return true;
if (root1 and root2 and root1 -> data == root2 -> data)
return (helper(root1 -> left, root2 -> right) and helper(root1 -> right, root2 -> left));
return false;
}
bool isSymmetry(struct treenode * root) {
return helper(root, root);
}
int main() {
struct treenode * root = NULL;
root = createNode(4);
root -> left = createNode(2);
root -> right = createNode(2);
root -> left -> right = createNode(7);
root -> left -> left = createNode(5);
root -> right -> left = createNode(5);
root -> right -> right = createNode(7);
if (isSymmetry(root)) {
cout << "True" << endl;
} else {
cout << "False" << endl;
}
return 0;
}
上記のコードを実行すると、次の出力が得られます。
実行結果
False
説明:
このコードでは、ルートの左右に配置された子の値の組み合わせ(5 と 7 の位置)が鏡像になっていないため、与えられた木は対称ではないと判断され、出力は False になります。
-
【C++】二分探索木から奇数の値を持つノードをすべて出力する方法
この記事では、二分探索木(BST)が与えられたときに、奇数の値を持つすべてのノードを出力する方法を解説します。二分探索木とは二分探索木は、以下の性質を持つ特殊な木構造です。左部分木には、必ずルートノードより小さい値が格納される右部分木には、必ずルートノードより大きい値が格納される左右どちらの部分木も、上記の2つの性質を満たす必要がある具体例を見て、問題を確認してみましょう。入力となる二分探索木:出力: 1 3 9解法のアプローチこの問題を解く最もシンプルな方法は、木全体を走査することです。走査の過程で各ノードの値をチェックし、その値が奇数であれば出力し、偶数であれば何もせず次のノードへ進みます
-
C++で二分木のルートから特定ノードまでの距離を求める方法
二分木が与えられたとき、ルートから特定のノード u までの距離(経路の長さ)を求める問題を考えてみましょう。例として、次のような二分木を想定します。この木において、ルートからノード6までの距離は2、ルートからノード8までの距離は3となります。解決のアプローチこの問題は、再帰的な手法を用いて解くことができます。具体的には、目的のノードを左部分木と右部分木の両方に対して再帰的に探索し、再帰の各段階(レベル)で距離を1ずつ加算していきます。探索の仕組みは以下の通りです。現在のノードがNULLの場合は -1 を返します(ノードが見つからなかったことを示す)。現在のノードの値が目的の値と一致した場合、ま