🧠 0.1: Python'da Bellek ve Referanslar

Linked List ve BST için Temel Kavramlar

🎯 Neden Bu Konuyu Öğrenmeliyiz?

Linked List ve Binary Search Tree gibi veri yapılarını anlamak için referans (pointer) kavramını bilmek gerekir.

📌 Temel Fikir

Python'da bir değişken değerin kendisini değil, o değerin bellekteki adresini (referansını) tutar.

Bu, C'deki pointer kavramına benzer!

🔍 id() Fonksiyonu: Bellek Adresini Görme

id(obj) fonksiyonu, bir objenin bellekteki benzersiz kimliğini (adresini) döndürür.

Python Kodu
# Basit değerler
a = 42
b = 42
c = 43

print("=" * 50)
print("🔢 TAM SAYILAR")
print("=" * 50)
print(f"a = {a}, id(a) = {id(a)}")
print(f"b = {b}, id(b) = {id(b)}")
print(f"c = {c}, id(c) = {id(c)}")

print(f"\na ve b aynı obje mi? {a is b}")  # True! Python küçük sayıları cache'ler
print(f"a ve c aynı obje mi? {a is c}")    # False

print("\n" + "=" * 50)
print("📝 STRING'LER")
print("=" * 50)
s1 = "merhaba"
s2 = "merhaba"
s3 = "dünya"

print(f"s1 = '{s1}', id(s1) = {id(s1)}")
print(f"s2 = '{s2}', id(s2) = {id(s2)}")
print(f"s3 = '{s3}', id(s3) = {id(s3)}")

print(f"\ns1 ve s2 aynı obje mi? {s1 is s2}")  # True! String interning

print("\n" + "=" * 50)
print("📦 LİSTELER")
print("=" * 50)
liste1 = [1, 2, 3]
liste2 = [1, 2, 3]
liste3 = liste1  # Aynı listeye referans!

print(f"liste1 = {liste1}, id(liste1) = {id(liste1)}")
print(f"liste2 = {liste2}, id(liste2) = {id(liste2)}")
print(f"liste3 = {liste3}, id(liste3) = {id(liste3)}")

print(f"\nliste1 ve liste2 aynı obje mi? {liste1 is liste2}")  # False! Farklı listeler
print(f"liste1 ve liste3 aynı obje mi? {liste1 is liste3}")    # True! Aynı liste
Çıktı bekleniyor...

📊 Görsel: Değişkenler ve Referanslar

1️⃣ İmmutable (Değiştirilemez) Tipler

int, str, tuple gibi tipler değiştirilemez. Aynı değer = aynı adres (genellikle).

a
0x7f123456
42
b

a ve b aynı 42 objesini gösteriyor (aynı adres)

2️⃣ Mutable (Değiştirilebilir) Tipler

list, dict, set gibi tipler değiştirilebilir. Her oluşturma yeni adres!

liste1
0x7f111111
[1,2,3]


liste2
0x7f222222
[1,2,3]

liste1 ve liste2 aynı içeriğe sahip ama FARKLI objeler!

⚠️ Tehlikeli Durum: Aliasing (Takma Ad)

Python Kodu
# ⚠️ ALİASİNG: İki değişken aynı objeyi gösterirse...

print("=" * 50)
print("⚠️ ALIASING PROBLEMİ")
print("=" * 50)

# liste1 oluştur
liste1 = [1, 2, 3]
print(f"liste1 başlangıç: {liste1}")

# liste2'yi liste1'e eşitle (KOPYA DEĞİL, REFERANS!)
liste2 = liste1
print(f"liste2 = liste1 sonrası")
print(f"  liste1: {liste1}, id: {id(liste1)}")
print(f"  liste2: {liste2}, id: {id(liste2)}")

# liste2'yi değiştir
print("\n⚡ liste2.append(4) yapıyoruz...")
liste2.append(4)

print(f"\n❌ Sonuç:")
print(f"  liste1: {liste1}")  # liste1 de değişti!
print(f"  liste2: {liste2}")
print(f"\n  İkisi de aynı obje: {liste1 is liste2}")

print("\n" + "=" * 50)
print("✅ ÇÖZÜM: KOPYA OLUŞTUR")
print("=" * 50)

# Yeni baştan
liste1 = [1, 2, 3]
liste2 = liste1.copy()  # veya liste1[:] veya list(liste1)

print(f"liste1: {liste1}, id: {id(liste1)}")
print(f"liste2 (kopya): {liste2}, id: {id(liste2)}")

liste2.append(4)
print(f"\nliste2.append(4) sonrası:")
print(f"  liste1: {liste1}")  # Değişmedi!
print(f"  liste2: {liste2}")
print(f"\n  Artık farklı objeler: {liste1 is liste2}")
Çıktı bekleniyor...

🔗 Linked List ile Bağlantı: Node Referansları

Python Kodu
# Linked List için Node sınıfı
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None  # Başlangıçta hiçbir yere işaret etmiyor

# Node'lar oluştur
node_a = Node("A")
node_b = Node("B")
node_c = Node("C")

print("=" * 60)
print("🔗 NODE'LAR VE REFERANSLARI")
print("=" * 60)

print(f"\nnode_a: data={node_a.data}, id={id(node_a)}")
print(f"node_b: data={node_b.data}, id={id(node_b)}")
print(f"node_c: data={node_c.data}, id={id(node_c)}")

# Bağlantıları kur
print("\n⛓️ Bağlantıları kuruyoruz...")
node_a.next = node_b  # A -> B
node_b.next = node_c  # B -> C

print(f"\nnode_a.next = {node_a.next} (id: {id(node_a.next)})")
print(f"node_b       = {node_b}      (id: {id(node_b)})")
print(f"Aynı obje mi? {node_a.next is node_b}")

print("\n" + "=" * 60)
print("🚶 LİSTEYİ GEZELİM")
print("=" * 60)

current = node_a  # Baştan başla
step = 1
while current is not None:
    next_info = f"→ {current.next.data}" if current.next else "→ None"
    print(f"Adım {step}: data={current.data}, id={id(current)} {next_info}")
    current = current.next  # Sonraki node'a geç
    step += 1

print("\n💡 Gördüğünüz gibi, her node bir sonrakinin REFERANSINI tutuyor!")
print("   Bu 'pointer' mantığının Python versiyonudur.")
Çıktı bekleniyor...

📚 == vs is Farkı

Operatör Karşılaştırma Örnek
== Değer eşitliği [1,2] == [1,2] → True
is Kimlik eşitliği (aynı obje mi?) [1,2] is [1,2] → False
Python Kodu
# == vs is

a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(f"a = {a}")
print(f"b = {b}")
print(f"c = a")

print(f"\na == b: {a == b}")  # True - değerler eşit
print(f"a is b: {a is b}")    # False - farklı objeler

print(f"\na == c: {a == c}")  # True - değerler eşit
print(f"a is c: {a is c}")    # True - AYNI obje!

# None kontrolü için is kullanın
print(f"\n📌 None kontrolü:")
x = None
print(f"x == None: {x == None}")  # Çalışır ama...
print(f"x is None: {x is None}")  # Tercih edilen yöntem!
Çıktı bekleniyor...

📊 Özet

Kavram Açıklama Örnek
id() Objenin bellek kimliği id(x)
is Aynı obje mi? a is b
Referans Değişken = objenin adresi x = obj
Aliasing İki isim, aynı obje b = a
Kopya Yeni obje oluştur b = a.copy()