BST Ekleme ve Arama
Özyinelemeli ve yinelemeli ekleme ile aramayı uygulayın, çeşitli anahtarlar için ağaçtaki yolu izleyin ve dengesiz ağaçların en kötü durum karmaşıklığını inceleyin.
BST Ekleme ve Arama, CoddyKit'te ücretsiz bir DSA Interview Prep dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DSA Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DSA Interview Prep kursu toplamda 4 dersten oluşur.
BST Özelliğinin Tanımı
Bir İkili Arama Ağacı tek bir değişmezi karşılar: her düğüm için, sol alt ağaçtaki tüm değerler düğümün değerinden kesinlikle küçüktür ve sağ alt ağaçtaki tüm değerler kesinlikle büyüktür. Yalnızca doğrudan çocuklarda değil, alt ağacın tamamında korunan bu sıralama özelliği; dengeli ağaçlarda O(log n) arama, ekleme ve silme işlemlerini mümkün kılar ve BST'yi genel bir ikili ağaçtan ayırır.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# Valid BST:
# 4
# / \
# 2 6
# / \ / \
# 1 3 5 7
# For node 4: left subtree {1,2,3} < 4 < right subtree {5,6,7}
# This holds recursively for EVERY node in the tree.
print('BST property: left < node < right at every level')Özyinelemeli BST Araması
BST araması ikili arama gibi çalışır: hedefi geçerli düğümün değeriyle karşılaştırın ve uygun alt ağaçta özyinelemeli olarak ilerleyin. Hedef geçerli değere eşitse düğümü döndürün. Hedef daha küçükse sola, daha büyükse sağa gidin. Boş bir düğüme ulaşırsanız boş değer döndürün. Zaman karmaşıklığı O(h)'dir — dengeli ağaçlarda O(log n), çarpık ağaçlarda O(n).
def search_bst(root, val):
if not root:
return None # not found
if root.val == val:
return root # found
if val < root.val:
return search_bst(root.left, val)
else:
return search_bst(root.right, val)
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
result = search_bst(root, 2)
print(result.val if result else 'Not found') # 2
result = search_bst(root, 5)
print(result.val if result else 'Not found') # Not foundYinelemeli BST Araması
Yinelemeli arama, çağrı yığınının ek yükünü ortadan kaldırır ve üretim kodunda tercih edilir. Karşılaştırmalara göre sola veya sağa ilerleyen bir curr işaretçisi kullanın. Bu, üç durumlu basit bir koşul döngüsüdür: boş (bulunamadı), eşleşme (bulundu) veya yönü değiştirme. Yinelemeli arama da O(h) zaman kullanır; ancak özyinelemeli sürümdeki O(h) yerine O(1) bellek kullanır.
def search_bst_iterative(root, val):
curr = root
while curr:
if val == curr.val:
return curr
elif val < curr.val:
curr = curr.left
else:
curr = curr.right
return None # not found
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
node = search_bst_iterative(root, 3)
print(node.val if node else 'Not found') # 3
print(search_bst_iterative(root, 9)) # NoneÖzyinelemeli BST Ekleme
BST'ye ekleme, aramadakiyle aynı sol/sağ kararlarını izleyerek doğru konumu bulur ve ardından ulaşılan ilk null konumuna yeni bir TreeNode bağlar. Özyinelemeli yaklaşım, her alt ağacın (gerekirse yeni) kökünü döndürür: geçerli düğüm boşsa yeni bir TreeNode döndürün; aksi halde özyinelemeli çağrının sonucuyla root.left veya root.right değerini güncelleyin. Bu kalıp temizdir ve mülakat çözümlerinde yaygın olarak kullanılır.
def insert_bst(root, val):
if not root:
return TreeNode(val) # create new node here
if val < root.val:
root.left = insert_bst(root.left, val)
elif val > root.val:
root.right = insert_bst(root.right, val)
# val == root.val: duplicate, do nothing (or handle as needed)
return root
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root = insert_bst(root, 1)
root = insert_bst(root, 5)
# Tree is now: 4, left=2(left=1), right=7(left=5)
print(root.right.left.val) # 5Yinelemeli BST Ekleme
Yinelemeli ekleme, ekleme noktasına ulaşmadan önceki son boş olmayan düğümü takip etmek için bir parent işaretçisi kullanır. Aramadaki gibi ağaçta aşağı doğru ilerlerken üst düğümü ve en son hangi yöne gittiğinizi kaydedin. Boş değere ulaştığınızda yeni düğümü üst düğümün uygun tarafına bağlayın. Boş ağaç sınır durumunu (kökün null olması) her zaman ayrı olarak ele alın.
def insert_bst_iterative(root, val):
new_node = TreeNode(val)
if not root:
return new_node
curr = root
while True:
if val < curr.val:
if curr.left is None:
curr.left = new_node
break
curr = curr.left
else: # val > curr.val
if curr.right is None:
curr.right = new_node
break
curr = curr.right
return root
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root = insert_bst_iterative(root, 3)
print(root.left.right.val) # 3En Kötü Durum BST'si: Çarpık Ağaçlar
Bir BST'ye sıralı bir dizi eklerseniz, bağlı listeye dönüşen bir çarpık ağaç elde edersiniz. Arama, ekleme ve silme işlemlerinin tümü O(n) olur. Dengeli BST'lerin (AVL ağaçları, Kırmızı-Siyah ağaçlar) var olma nedeni budur. Mülakatlarda BST karmaşıklığı sorulduğunda bu en kötü durumu her zaman belirtin — “dengesiz ağaçlarda ortalama O(log n), en kötü durumda O(n)” demeniz konuya hakimiyetinizi gösterir.
# Inserting 1, 2, 3, 4, 5 into a BST:
# 1
# \
# 2
# \
# 3
# \
# 4
# \
# 5
# This is a right-skewed tree: search is O(n) not O(log n)
root = None
for val in [1, 2, 3, 4, 5]:
root = insert_bst(root, val)
# Verify the skew
node = root
depth = 0
while node:
depth += 1
node = node.right
print(f'Height: {depth}') # 5 = O(n), not O(log n)Minimum ve Maksimumu Bulma
Bir BST'de minimum değer her zaman en soldaki düğümdür (boşa ulaşana kadar sola ilerleyin); maksimum değer ise en sağdaki düğümdür. O(h) karmaşıklığındaki bu işlemler, BST silmede (sıralı geçişte ardılı bulma) ve aralık sorgularında alt yordam olarak sıkça kullanılır. Bu yardımcıları ezbere bilmek mülakatlarda zaman kazandırır.
def find_min(root):
while root.left:
root = root.left
return root
def find_max(root):
while root.right:
root = root.right
return root
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
root.right.right = TreeNode(9)
print(find_min(root).val) # 1
print(find_max(root).val) # 9Sıralı Geçişte Ardıl ve Öncel
Bir düğümün sıralı geçişte ardılı, o düğümden büyük en küçük değere sahip düğümdür. Düğümün bir sağ alt ağacı varsa ardıl find_min(node.right) olur. Sağ alt ağacı yoksa ardıl, verilen düğümün sol alt ağaçta bulunduğu en aşağıdaki atadır. Bunu anlamak, BST silme ve BST yineleyicisi problemleri için kritik öneme sahiptir.
def inorder_successor(root, p):
successor = None
while root:
if p.val < root.val:
successor = root # possible successor
root = root.left
else:
root = root.right
return successor
def inorder_predecessor(root, p):
predecessor = None
while root:
if p.val > root.val:
predecessor = root # possible predecessor
root = root.right
else:
root = root.left
return predecessor
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(6)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
p = root.left # node with val=2
print(inorder_successor(root, p).val) # 3
print(inorder_predecessor(root, p).val) # 1BST Arama Karmaşıklığı Analizi
BST performansı tamamen ağaç yüksekliğine bağlıdır. n düğümlü dengeli bir BST için yükseklik O(log n) olur; bu da arama, ekleme ve silme işlemlerinin O(log n) olmasını sağlar. Çarpık bir BST için yükseklik O(n) olur ve tüm işlemler O(n) sürer. Python'da Java'nın TreeMap'inin aksine yerleşik bir dengeli BST yoktur; bu nedenle AVL/Kırmızı-Siyah ağaçlarını kendiniz uygulayabilir, sortedcontainers.SortedList kullanabilir veya öncelik kuyruğu kullanım senaryoları için bir yığına güvenebilirsiniz.
# Python's BST alternatives:
# 1. heapq - min/max heap, O(log n) push/pop
# 2. sortedcontainers.SortedList (third-party, often allowed)
# 3. Manual AVL or Red-Black (rarely required in interviews)
# When interviews say 'use a BST':
# - LeetCode: implement TreeNode-based solution
# - Real interview: mention sortedcontainers or Java TreeMap equivalent
# - O(log n) operations matter when you need ordered access
# For pure insert/lookup without ordering: use dict (O(1) average)
print('Use heap for priority, dict for lookup, BST for ordered range')BST'ye Ekleme: Sınır Durumları
Ekleme işleminizin şunları ele aldığını her zaman doğrulayın: boş ağaç (yeni düğümü kök olarak döndürme), yinelenen değerler (yok sayılacaklarını, sola mı yoksa sağa mı ekleneceklerini belirleyin ve tutarlı olun) ve çok büyük veya çok küçük değerler. Mülakatlarda kod yazmaya başlamadan önce yinelenen değerlerle ilgili varsayımınızı belirtin. LeetCode problemlerindeki en yaygın kural, aksi belirtilmedikçe tüm değerlerin farklı olmasıdır.
def insert_bst_no_duplicates(root, val):
if not root:
return TreeNode(val)
if val < root.val:
root.left = insert_bst_no_duplicates(root.left, val)
elif val > root.val:
root.right = insert_bst_no_duplicates(root.right, val)
# else: val == root.val -> duplicate, skip
return root
# Test all edge cases:
root = None
root = insert_bst_no_duplicates(root, 5) # empty tree
root = insert_bst_no_duplicates(root, 5) # duplicate
root = insert_bst_no_duplicates(root, 3)
root = insert_bst_no_duplicates(root, 7)
print(root.val, root.left.val, root.right.val) # 5 3 7Sıralı Diziden BST
Sıralı bir diziden yüksekliği dengeli bir BST oluşturma (LeetCode #108), böl ve yönet yaklaşımını kullanır: orta öğe kök olur, sol yarı sol alt ağaca, sağ yarı ise sağ alt ağaca dönüşür. Bu yöntem, yüksekliği O(log n) olan dengeli bir ağaç oluşturmayı garanti eder. Her öğe yalnızca bir kez işlendiği için zaman karmaşıklığı O(n)'dir.
def sorted_array_to_bst(nums):
if not nums:
return None
mid = len(nums) // 2
root = TreeNode(nums[mid])
root.left = sorted_array_to_bst(nums[:mid])
root.right = sorted_array_to_bst(nums[mid+1:])
return root
nums = [-10, -3, 0, 5, 9]
root = sorted_array_to_bst(nums)
print(root.val) # 0 (middle element)
print(root.left.val) # -3
print(root.right.val) # 9Hızlı Kontrol
Bu dersteki Veri Yapıları & Algoritmalar — Kodlama Mülakatı Hazırlığı kavramlarını anlayıp anlamadığınızı test edin.
Ders Özeti
Bu derste şunları öğrendiniz: BST özelliği (sol alt ağaç kesinlikle daha küçük, sağ alt ağaç kesinlikle daha büyük), O(h) zamanda hem özyinelemeli hem yinelemeli arama ve ekleme ve yüksekliğin n'ye eşit olduğu en kötü durumdaki çarpık ağaçlar. Sırada BST silme işlemi ve bunun üç durumu var.
Sıkça Sorulan Sorular
“BST Ekleme ve Arama” dersi ücretsiz mi?
Evet — “BST Ekleme ve Arama” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DSA Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DSA Interview Prep kursu toplamda 4 dersten oluşur.
“BST Ekleme ve Arama” dersinde ne öğreneceğim?
Özyinelemeli ve yinelemeli ekleme ile aramayı uygulayın, çeşitli anahtarlar için ağaçtaki yolu izleyin ve dengesiz ağaçların en kötü durum karmaşıklığını inceleyin. DSA Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
DSA Interview Prep öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te DSA Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.
“BST Ekleme ve Arama” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu DSA Interview Prep dersinde kod yazıp çalıştırabilir miyim?
Evet. Her DSA Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- BST Ekleme ve Arama
- BST Silme: Üç Durum
- BST’yi ve Orta Sıralı Özellikleri Doğrulama
- K’inci En Küçük, Aralık Toplamı ve BST’den Sıralı Diziye