Pythonで二分木が赤黒木と同じように高さバランスされているかを判定する方法
問題の概要
赤黒木(Red-Black Tree)には「任意のノードにおける最大の高さは、最小の高さの2倍を超えない」という重要な性質があります。
この性質を一般の二分探索木に適用し、次の条件が成り立つかどうかを確認することを考えます。すべてのノードについて、そのノードから葉までの最長経路の長さが、最短経路上のノード数の2倍以下であること。
たとえば、次のような木が入力として与えられた場合、

この木はバランスが取れているため、出力は True になります。
解法のアプローチ
この問題は再帰的に解くことができます。手順は以下の通りです。
- 関数
solve()を定義します。引数はroot(現在のノード)、max_height、min_heightです。 rootが null の場合:max_height := 0、min_height := 0とするTrueを返す
left_max := 0、left_min := 0、right_max := 0、right_min := 0で初期化します。solve(root.left, left_max, left_min)の結果がFalseの場合はFalseを返します。solve(root.right, right_max, right_min)の結果がFalseの場合もFalseを返します。max_height := 左右の最大値 + 1を計算します。min_height := 左右の最小値 + 1を計算します。max_height <= 2 * min_heightが成り立てばTrueを返します。- それ以外は
Falseを返します。
メイン処理では、max_height と min_height を 0 で初期化し、solve(root, max_height, min_height) の結果を返します。
実装例
理解を深めるために、実際のPythonコードを見てみましょう。
class TreeNode:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
def solve(root, max_height, min_height):
if (root == None):
max_height = min_height = 0
return True
left_max = 0
left_min = 0
right_max, right_min = 0, 0
if (solve(root.left, left_max, left_min) == False):
return False
if (solve(root.right, right_max, right_min) == False):
return False
max_height = max(left_max, right_max) + 1
min_height = min(left_min, right_min) + 1
if (max_height <= 2 * min_height):
return True
return False
def is_tree_balanced(root):
max_height, min_height = 0, 0
return solve(root, max_height, min_height)
root = TreeNode(10)
root.left = TreeNode(5)
root.right = TreeNode(100)
root.right.left = TreeNode(50)
root.right.right = TreeNode(150)
root.right.left.left = TreeNode(40)
print(is_tree_balanced(root))入力
root = TreeNode(10) root.left = TreeNode(5) root.right = TreeNode(100) root.right.left = TreeNode(50) root.right.right = TreeNode(150) root.right.left.left = TreeNode(40)
出力
True
まとめ
このアルゴリズムは、木を再帰的に走査しながら各部分木の最長・最短の高さを求め、「最長経路 ≤ 最短経路 × 2」という赤黒木の平衡条件を満たすかどうかを判定します。計算量は各ノードを一度ずつ訪問するため O(n) となり、効率的に木のバランス状態を確認できます。
-
Pythonで二分木を反転する方法:再帰を使った実装を解説
二分木の反転とは二分木が与えられたとき、その左右の子ノードを入れ替えて「鏡像」のような木を作ることを二分木の反転(Invert Binary Tree)と呼びます。これはアルゴリズムの学習やコーディング面接でも頻出のトピックです。例えば、次のような二分木があったとします。これを反転すると、すべてのノードの左部分木と右部分木が入れ替わり、以下のような木になります。解き方:再帰的アプローチこの問題は再帰を使うと非常にシンプルに解けます。考え方は以下の3ステップです。ルートが None(null)であれば、そのまま返す(ベースケース)現在のノードの左ポインタと右ポインタを入れ替える左部分木と右部分木
-
Pythonでソート済み配列を高さバランスの二分探索木に変換する方法
ソートされた配列 A が与えられたとき、そこから高さバランスの取れた二分探索木(BST)を生成することを考えます。ここで「高さバランスの取れた二分木」とは、すべてのノードにおいて、左右の部分木の深さの差が常に1以下であるような二分木のことを指します。例として、配列が [-10, -3, 0, 5, 9] の場合、出力の一例は [0, -3, 9, -10, null, 5] のようになります。解法のアプローチこの問題は、配列の中央要素をルートに選ぶというシンプルな発想で解くことができます。具体的な手順は以下の通りです。配列 A が空の場合は、Null(None)を返します。配列の中央の要素を見