Anahtarı İndekse Dönüştürmek - Basit ve Anlaşılır
Hash fonksiyonu, herhangi bir veriyi (anahtar) alıp, onu bir sayıya (indeks) dönüştüren matematiksel bir fonksiyondur.
Kütüphanede kitaplar konularına göre raflara yerleştirilir:
Hash fonksiyonu, kitap konusunu (anahtar) alıp raf numarasını (indeks) veriyor!
Bir kelime girin ve farklı hash fonksiyonlarının nasıl çalıştığını görün
İyi bir hash fonksiyonu şu özelliklere sahip olmalıdır:
Hash hesaplama çok hızlı olmalı (O(1) zaman)
Anahtarları tabloya eşit şekilde dağıtmalı
Aynı anahtar her zaman aynı indeksi vermeli
En basit ve en yaygın kullanılan yöntem!
(key'i table_size'a böl, kalanı al)
Tablo boyutu: 10
hash(25) = 25 % 10 = 5hash(38) = 38 % 10 = 8hash(123) = 123 % 10 = 3✅ Sayısal anahtarlar için (ID, telefon numarası, etc.)
✅ Basit ve hızlı
✅ Anlaşılması kolay
Tablo boyutunu asal sayı seçin! (7, 11, 13, 17, 19...)
Bu, daha iyi dağılım sağlar ve çakışmaları azaltır.
def hash_division(key, table_size):
"""Bölme yöntemi ile hash hesapla"""
return key % table_size
# Örnek kullanım
table_size = 11 # Asal sayı - önemli!
# Farklı anahtarlar için hash değerleri
keys = [25, 38, 123, 456, 789]
print(f"Tablo boyutu: {table_size}")
print(f"{'Anahtar':<10} {'Hash Değeri':<15}")
print("-" * 25)
for key in keys:
hash_value = hash_division(key, table_size)
print(f"{key:<10} {hash_value:<15}")
# String anahtarlar için
def hash_string_division(text, table_size):
"""String'i önce sayıya çevir, sonra hash hesapla"""
# Karakterlerin ASCII değerlerini topla
total = sum(ord(char) for char in text)
return total % table_size
print("\n=== String Anahtarlar ===")
words = ["elma", "armut", "muz", "çilek"]
print(f"{'Kelime':<10} {'ASCII Toplamı':<15} {'Hash':<10}")
print("-" * 35)
for word in words:
ascii_sum = sum(ord(c) for c in word)
hash_val = hash_string_division(word, table_size)
print(f"{word:<10} {ascii_sum:<15} {hash_val:<10}")
Daha gelişmiş bir yöntem - tablo boyutundan bağımsız çalışır!
A: 0 ile 1 arasında bir sabit (genelde: 0.6180339887... - altın oran)
m: Tablo boyutu
mod 1: Sadece ondalık kısmı al
key = 123, A = 0.618, m = 10
import math
def hash_multiplication(key, table_size):
"""Çarpma yöntemi ile hash hesapla"""
# Altın oran (golden ratio)
A = 0.6180339887
# key × A'nın ondalık kısmını al
fractional = (key * A) % 1
# Tablo boyutu ile çarp ve tam kısmı al
return int(table_size * fractional)
# Örnek kullanım
table_size = 16 # 2'nin kuvveti - multiplication için iyi
keys = [25, 38, 123, 456, 789, 1000]
print(f"Tablo boyutu: {table_size}")
print(f"A sabiti: 0.6180339887 (Altın Oran)")
print()
print(f"{'Anahtar':<10} {'key × A':<15} {'Ondalık':<12} {'Hash':<10}")
print("-" * 47)
for key in keys:
product = key * 0.6180339887
fractional = product % 1
hash_val = hash_multiplication(key, table_size)
print(f"{key:<10} {product:<15.4f} {fractional:<12.4f} {hash_val:<10}")
# Karşılaştırma: Division vs Multiplication
print("\n=== Division vs Multiplication Karşılaştırma ===")
print(f"{'Anahtar':<10} {'Division':<15} {'Multiplication':<15}")
print("-" * 40)
for key in keys:
div_hash = key % table_size
mult_hash = hash_multiplication(key, table_size)
print(f"{key:<10} {div_hash:<15} {mult_hash:<15}")
Python'da yerleşik gelen hash fonksiyonu - çok gelişmiş ve optimize edilmiş!
# Python'un yerleşik hash fonksiyonu
# Sayılar için
print("=== Sayılar ===")
numbers = [1, 42, 123, 1000, -50]
for num in numbers:
print(f"hash({num:>5}) = {hash(num)}")
# String'ler için
print("\n=== String'ler ===")
words = ["elma", "armut", "muz", "python", "algoritma"]
for word in words:
print(f"hash('{word:<10}') = {hash(word)}")
# Tuple için (değiştirilemez)
print("\n=== Tuple (çalışır) ===")
my_tuple = (1, 2, 3)
print(f"hash({my_tuple}) = {hash(my_tuple)}")
# Hash table için kullanım
print("\n=== Hash Table Kullanımı ===")
table_size = 10
# String anahtarları hash'le ve tabloya yerleştir
keys = ["elma", "armut", "muz"]
for key in keys:
hash_value = hash(key)
index = hash_value % table_size # Tabloya sığdır
print(f"'{key}' -> hash: {hash_value:>10} -> indeks: {index}")
# ❌ List için çalışmaz
print("\n=== ❌ List (çalışmaz) ===")
try:
my_list = [1, 2, 3]
print(hash(my_list))
except TypeError as e:
print(f"HATA: {e}")
print("List değiştirilebilir olduğu için hash'lenemez!")
| Durum | Önerilen Yöntem | Neden? |
|---|---|---|
| Sayısal anahtarlar | Division | Basit, hızlı, yeterli |
| String anahtarlar | Python hash() | Optimize edilmiş, güvenilir |
| Kötü dağılım | Multiplication | Daha iyi dağılım sağlar |
| Eğitim/Öğrenme | Division | Anlaşılması en kolay |
| Gerçek projeler | Python dict | Yerleşik, güvenli, hızlı |
Aynı anahtar her zaman aynı hash değerini vermelidir!
Hash hesaplama O(1) zamanda olmalı - karmaşık işlemlerden kaçının!
Tüm indeksler eşit şansla kullanılmalı - tek bir yerde toplanmamalı!
Hash fonksiyonları bazen aynı indeksi verir - buna çakışma (collision) denir. Bir sonraki bölümde çakışmaları nasıl çözeceğimizi öğreneceğiz!