二分探索木(Binary Search Tree, BST)は、ノードが左の子ノードよりも小さく、右の子ノードよりも大きいという特性を持つデータ構造です。この特性により、探索、挿入、削除の操作が効率良く行えます。この教材では、二分探索木の基本操作である挿入、削除、探索について学びます。
まず、二分探索木を表すためのノードクラスを定義します。
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
このクラスは、各ノードが持つ値(val
)、左の子ノード(left
)、右の子ノード(right
)を表します。
次に、二分探索木にノードを挿入するための関数を実装します。
def insert(root, key):
if root is None:
return Node(key)
else:
if key < root.val:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
return root
root
がNone
の場合、新しいノードを作成して返します。key
が現在のノードの値より小さい場合、左の子ノードに挿入します。次に、二分探索木から特定の値を探索する関数を実装します。
def search(root, key):
if root is None or root.val == key:
return root
if key < root.val:
return search(root.left, key)
return search(root.right, key)
root
がNone
またはroot.val
がkey
と等しい場合、ノードを返します。key
が現在のノードの値より小さい場合は、左の子ノードを探索します。最後に、二分探索木からノードを削除するための関数を実装します。
def delete_node(root, key):
if root is None:
return root
if key < root.val:
root.left = delete_node(root.left, key)
elif key > root.val:
root.right = delete_node(root.right, key)
else:
# ノードが見つかった場合
if root.left is None:
return root.right
elif root.right is None:
return root.left
# 両方の子が存在する場合
min_larger_node = find_min(root.right)
root.val = min_larger_node.val
root.right = delete_node(root.right, min_larger_node.val)
return root
def find_min(node):
current = node
while current.left is not None:
current = current.left
return current
これまでの関数を使って、二分探索木を操作する例を示します。
if __name__ == "__main__":
root = None
keys = [20, 30, 10, 5, 15, 25, 35]
# ノードの挿入
for key in keys:
root = insert(root, key)
# ノードの探索
search_key = 15
found_node = search(root, search_key)
if found_node:
print(f"Node with key {search_key} found.")
else:
print(f"Node with key {search_key} not found.")
# ノードの削除
root = delete_node(root, 20)
print("Node with key 20 deleted.")
これで、二分探索木の基本操作(挿入、削除、探索)についての解説は完了です。これらの基本操作を理解することで、データ構造の効率的な運用が可能となります。