Binary Search Tree - Hızlı Arama için Ağaç Yapısı
Ağaç, hiyerarşik bir veri yapısıdır. Linked List'in genelleştirilmiş halidir:
Her node için:
Bu kural sayesinde arama O(log n) olur!
Değer girin ve "Ekle" butonuna tıklayın
BST node'u, linked list node'una benzer ama iki referans içerir:
# BST için Node sınıfı
class Node:
def __init__(self, data):
self.data = data # Saklanan değer
self.left = None # Sol çocuğa referans (küçükler)
self.right = None # Sağ çocuğa referans (büyükler)
# Örnek: Basit bir ağaç oluşturalım
# 50
# / \
# 30 70
# / \ / \
# 20 40 60 80
root = Node(50)
root.left = Node(30)
root.right = Node(70)
root.left.left = Node(20)
root.left.right = Node(40)
root.right.left = Node(60)
root.right.right = Node(80)
# Yapıyı kontrol edelim
print("🌳 Ağaç Yapısı:")
print(f"Kök: {root.data}")
print(f" Sol çocuk: {root.left.data}")
print(f" Sol-sol: {root.left.left.data}")
print(f" Sol-sağ: {root.left.right.data}")
print(f" Sağ çocuk: {root.right.data}")
print(f" Sağ-sol: {root.right.left.data}")
print(f" Sağ-sağ: {root.right.right.data}")
# BST kuralını kontrol edelim
print("\n✅ BST Kuralı Kontrolü:")
print(f" 30 < 50 < 70? {root.left.data} < {root.data} < {root.right.data}")
print(f" 20 < 30 < 40? {root.left.left.data} < {root.left.data} < {root.left.right.data}")
print(f" 60 < 70 < 80? {root.right.left.data} < {root.right.data} < {root.right.right.data}")
| Arama: | O(n) (sıralıysa O(log n)) |
| Ekleme: | O(n) (kaydırma gerekir) |
| Silme: | O(n) (kaydırma gerekir) |
| Arama: | O(n) |
| Ekleme (başa): | O(1) |
| Silme: | O(n) (arama + O(1)) |
| Arama: | O(log n) ✨ |
| Ekleme: | O(log n) ✨ |
| Silme: | O(log n) ✨ |
Eğer elemanlar sıralı eklenirse (1, 2, 3, 4, 5...), BST bir "linked list"e dönüşür ve performans O(n) olur!
Bu problemi çözmek için AVL Tree veya Red-Black Tree gibi dengeli ağaçlar kullanılır.
Aradığımız değer: 40
Sadece 3 karşılaştırma ile 7 elemanlı ağaçta değeri bulduk!
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def search(root, target):
"""BST'de arama - O(log n)"""
steps = 0
current = root
while current is not None:
steps += 1
print(f"Adım {steps}: {current.data} ile karşılaştır", end=" → ")
if target == current.data:
print(f"BULUNDU! ✅")
return current, steps
elif target < current.data:
print(f"{target} < {current.data}, SOLA git")
current = current.left
else:
print(f"{target} > {current.data}, SAĞA git")
current = current.right
print("Bulunamadı ❌")
return None, steps
# Ağacı oluştur
root = Node(50)
root.left = Node(30)
root.right = Node(70)
root.left.left = Node(20)
root.left.right = Node(40)
root.right.left = Node(60)
root.right.right = Node(80)
print("🌳 Ağaç: 50 → (30, 70) → (20, 40, 60, 80)\n")
# Farklı değerleri ara
for target in [40, 80, 25, 50]:
print(f"\n🔍 {target} aranıyor:")
result, steps = search(root, target)
print(f" Toplam adım: {steps}")
Dizide arama: 1 milyon elemanda → 1.000.000 karşılaştırma (O(n))
BST'de arama: 1 milyon elemanda → sadece ~20 karşılaştırma (O(log n))
Bu fark, gerçek dünya uygulamalarında hayati önem taşır!