Python'un Yerleşik Heap Kütüphanesi
Daha önce heap veri yapısını sıfırdan nasıl yazacağımızı gördük. Ama iyi haber: Python bize hazır bir heap
modülü sunuyor! heapq modülü sayesinde heap işlemlerini tek satırda yapabiliriz.
Python'un heapq modülünün özelliği şu: ayrı bir Heap sınıfı yok. Bunun yerine
normal bir Python listesini heap olarak kullanır ve bize heappush, heappop gibi
fonksiyonlar sağlar. Liste arka planda otomatik olarak heap özelliğini korur.
Python heapq modülü sadece Min Heap destekler. Yani en küçük eleman her zaman kökte
(heap[0]'da) bulunur ve heappop() her zaman en küçük elemanı döndürür.
Peki Max Heap istiyorsam? Çözüm basit: Değerleri negatif yapın!
# Max Heap trick - negatif kullanımı
heap = []
heapq.heappush(heap, -10) # 10'u eklemek için -10 kullan
heapq.heappush(heap, -30) # 30'u eklemek için -30 kullan
heapq.heappush(heap, -20) # 20'yi eklemek için -20 kullan
# En büyüğü çıkar: -(-30) = 30
biggest = -heapq.heappop(heap) # 30 döner!
Açıklama: Heap'e eleman ekler (O(log n))
Kullanım: heapq.heappush(my_heap, 5)
Açıklama: En küçük elemanı çıkarır ve döndürür (O(log n))
Kullanım: smallest = heapq.heappop(my_heap)
Açıklama: Listeyi heap'e çevirir (O(n))
Kullanım: heapq.heapify(my_list)
Açıklama: Push + Pop tek işlemde (daha verimli)
Kullanım: result = heapq.heappushpop(heap, 10)
Açıklama: En büyük/küçük n elemanı döndürür
Kullanım: top3 = heapq.nlargest(3, my_list)
import heapq
print("=== heapq Temel Kullanım ===\n")
# 1. Boş heap oluştur
heap = []
print(f"Boş heap: {heap}")
# 2. Eleman ekle (heappush)
heapq.heappush(heap, 5)
heapq.heappush(heap, 3)
heapq.heappush(heap, 7)
heapq.heappush(heap, 1)
print(f"Push sonrası: {heap}")
print(f"Min eleman (heap[0]): {heap[0]}")
# 3. En küçüğü çıkar (heappop)
smallest = heapq.heappop(heap)
print(f"\nPop: {smallest}")
print(f"Kalan heap: {heap}")
# 4. Listeyi heap'e çevir (heapify)
print("\n=== heapify ===")
data = [9, 4, 7, 1, 3, 8]
print(f"Önce: {data}")
heapq.heapify(data)
print(f"Sonra: {data}")
# 5. nlargest ve nsmallest
print("\n=== nlargest / nsmallest ===")
numbers = [15, 3, 8, 21, 7, 42, 1, 99]
print(f"Liste: {numbers}")
print(f"En büyük 3: {heapq.nlargest(3, numbers)}")
print(f"En küçük 3: {heapq.nsmallest(3, numbers)}")
import heapq
print("=== MAX HEAP (Negatif Trick) ===\n")
# Değerleri negatif yaparak max heap simüle et
max_heap = []
values = [10, 30, 20, 50, 40]
print(f"Eklenecek değerler: {values}")
# Negatif olarak ekle
for val in values:
heapq.heappush(max_heap, -val)
print(f" Push {val} → heap: {[-x for x in max_heap]}")
print(f"\nMax heap (gerçek değerler): {[-x for x in max_heap]}")
print(f"Max eleman: {-max_heap[0]}")
# Pop ederken pozitife çevir
print("\nMax'tan küçüğe sırayla çıkar:")
while max_heap:
value = -heapq.heappop(max_heap)
print(f" Pop: {value}")
# ===== Alternatif: nlargest =====
print("\n" + "=" * 40)
print("Alternatif: Sadece en büyük N lazımsa")
print("=" * 40)
data = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"Data: {data}")
print(f"En büyük 4: {heapq.nlargest(4, data)}")
print("(Heap kurmaya gerek yok!)")
import heapq
print("=== Tuple ile Priority Queue ===\n")
# (öncelik, veri) formatında
tasks = []
# Görevleri ekle
heapq.heappush(tasks, (2, "Rapor hazırla"))
heapq.heappush(tasks, (1, "ACİL: Sunuma hazırlan")) # En öncelikli
heapq.heappush(tasks, (3, "Mail cevapla"))
heapq.heappush(tasks, (1, "ACİL: Toplantıya git"))
print("Görevler öncelik sırasında:")
while tasks:
priority, task = heapq.heappop(tasks)
print(f" [{priority}] {task}")
# ===== Obje ile kullanım =====
print("\n" + "=" * 40)
print("Nesne ile kullanım (key fonksiyonu)")
print("=" * 40)
class Task:
def __init__(self, name, priority):
self.name = name
self.priority = priority
def __repr__(self):
return f"Task({self.name}, p={self.priority})"
# Wrapper ile
task_list = [
(3, Task("Email", 3)),
(1, Task("Sunuş", 1)),
(2, Task("Kod", 2)),
]
heapq.heapify(task_list)
print("Task objeler (öncelik sırasında):")
while task_list:
priority, task = heapq.heappop(task_list)
print(f" {task}")
| Özellik | heapq | Sıralı Liste | queue.PriorityQueue |
|---|---|---|---|
| Push | O(log n) ✅ | O(n) | O(log n) |
| Pop | O(log n) ✅ | O(1) | O(log n) |
| Thread-safe | ❌ Hayır | ❌ Hayır | ✅ Evet |
| Kullanım | Tek thread, hız önemli | Küçük veri, basit | Multi-thread |