Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで二分木が赤黒木と同じように高さバランスされているかを判定する方法

問題の概要

赤黒木(Red-Black Tree)には「任意のノードにおける最大の高さは、最小の高さの2倍を超えない」という重要な性質があります。

この性質を一般の二分探索木に適用し、次の条件が成り立つかどうかを確認することを考えます。すべてのノードについて、そのノードから葉までの最長経路の長さが、最短経路上のノード数の2倍以下であること

たとえば、次のような木が入力として与えられた場合、

Pythonで二分木が赤黒木と同じように高さバランスされているかを判定する方法

この木はバランスが取れているため、出力は True になります。

解法のアプローチ

この問題は再帰的に解くことができます。手順は以下の通りです。

  • 関数 solve() を定義します。引数は root(現在のノード)、max_heightmin_height です。
  • root が null の場合:
    • max_height := 0min_height := 0 とする
    • True を返す
  • left_max := 0left_min := 0right_max := 0right_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_heightmin_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) となり、効率的に木のバランス状態を確認できます。

  1. Pythonで二分木を反転する方法:再帰を使った実装を解説

    二分木の反転とは二分木が与えられたとき、その左右の子ノードを入れ替えて「鏡像」のような木を作ることを二分木の反転(Invert Binary Tree)と呼びます。これはアルゴリズムの学習やコーディング面接でも頻出のトピックです。例えば、次のような二分木があったとします。これを反転すると、すべてのノードの左部分木と右部分木が入れ替わり、以下のような木になります。解き方:再帰的アプローチこの問題は再帰を使うと非常にシンプルに解けます。考え方は以下の3ステップです。ルートが None(null)であれば、そのまま返す(ベースケース)現在のノードの左ポインタと右ポインタを入れ替える左部分木と右部分木

  2. Pythonでソート済み配列を高さバランスの二分探索木に変換する方法

    ソートされた配列 A が与えられたとき、そこから高さバランスの取れた二分探索木(BST)を生成することを考えます。ここで「高さバランスの取れた二分木」とは、すべてのノードにおいて、左右の部分木の深さの差が常に1以下であるような二分木のことを指します。例として、配列が [-10, -3, 0, 5, 9] の場合、出力の一例は [0, -3, 9, -10, null, 5] のようになります。解法のアプローチこの問題は、配列の中央要素をルートに選ぶというシンプルな発想で解くことができます。具体的な手順は以下の通りです。配列 A が空の場合は、Null(None)を返します。配列の中央の要素を見