Basit Karma Tabloya Genel Bakış
Tazeleme olarak, karma tablo, bir veri yapısındaki belirli bir anahtarın altındaki bir değeri saklamanın bir yoludur. Örneğin "a"
, anahtarı anahtarın altında saklayabilir 1
ve daha sonra 1
hash tablosundaki anahtarı arayarak alabilirim .
Kafamın üstünden düşünebildiğim en basit tablo, sadece tamsayıları saklayabilen bir karma tablodur; buradaki karma tablo girişi için anahtar aynı zamanda depolanan değerdir. Diyelim ki masanız 8 beden ve temelde bellekteki bir dizi:
---------------------------------
| | | | | | | | |
---------------------------------
0 1 2 3 4 5 6 7
Özet fonksiyonu
Karma işlevleri, değerinizi nereye kaydedeceğinize dair bir dizin verir. Bu tablo için oldukça basit bir hash fonksiyonu saklamak istediğiniz değere 1 ekleyin ve sonra olacaktır mod 8 (tablo boyutu) bunu. Başka bir deyişle, karma fonksiyonudur (n+1)%8
, nerede n
saklamak istediğiniz tam sayıdır.
ekler
Bu karma tabloya bir değer (n+1)%8
eklemek istiyorsanız, size bir dizin vermek için eklemek istediğiniz değer üzerindeki karma işlevinizi çağırın (bu durumda ). Mesela, eğer 14 eklemek istiyorsak, (14 + 1) % 8
index'i çağırır ve 7
alırdık, böylece onu index'e eklerdik 7
.
---------------------------------
| | | | | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
Benzer şekilde, 33, 82 ve 191 gibi ekleyebilirsiniz:
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
Çarpışmalar
Ancak bir girişle çarpışacak bir şey eklemeye çalışırsak ne olur? 2 endekse girmelidir 3
, ancak 82 tarafından alınmaktadır. Bu sorunu çözmek için birden fazla yol vardır, en basit olanı boş bir boşluk bulana kadar tekrar tekrar karma fonksiyonunu çağırmaktır.
Yani mantık aşağıdaki gibidir:
- (2 + 1)% 8 = 3
- Dizin 3 dolu
- Hash fonksiyonumuza tekrar 3 takın . ( 3 + 1)% 8 = 4 , boş.
- Değerimizi dizin 4'e yerleştirin .
Şimdi, karma tablo şöyle görünür, 2 değeri indekste saklanır 4
.
---------------------------------
|191| |33 |82 |2 | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
Bu çözümün dezavantajı, çok yakında, masamızın dolması! Veri boyutunuzun sınırlı olduğunu biliyorsanız, tablonuzun tüm olası değerleri tutacak kadar büyük olması koşuluyla bu sorun olmamalıdır. Daha fazla tutabilmek istiyorsanız, çarpışmaları farklı şekilde ele alabilirsiniz. 2 eklemeden önce bulunduğumuz yere geri dönelim.
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
Hatırlarsanız, alınan (2+1)%8
indeksi bize verir 3
. Karma tablonuzun dolmasını istemiyorsanız, her tablo endeksini bağlantılı liste olarak kullanabilir ve o dizindeki listeye ekleyebilirsiniz. Böylece tekrar karma işlevini çağırmak yerine, sadece indeksindeki listeye ekleyeceğiz 3
:
-----
| 2 |
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
Bu liste daha sonra hafızanın izin verdiği kadar büyüyebilir. 18 ekleyebilirim, ve sadece 2 eklenir:
-----
|18 |
-----
| 2 |
---------------------------------
|191| |33 |82 | | | |14 |
---------------------------------
0 1 2 3 4 5 6 7
aramaları
Karma tablonuzdaki arama değerleri, karma tablonuz oldukça büyük bir boyutta olduğu için hızlıdır. Sen sadece hash fonksiyonunu çağır ve dizini al. Diyelim ki 82 masanızda mı görmek istiyorsunuz. Arama işlevi (82+1)%8
= 3
öğesini çağırır ve dizindeki öğeye bakar 3
ve sizin için döndürür. Eğer 16'yı aradıysanız, arama fonksiyonu indekse bakar 1
ve var olmadığını görür.
Aramalar Çarpışmalarla da Başa Çıkmanız Gerekiyor!
2 değerini aramaya çalışırsanız, karma tablonuz, verileri almak için olduğu gibi verileri depolamak için kullanılan aynı çarpışma mantığını kullanmak zorunda kalır. Karma tablonuzun çalışma biçimine bağlı olarak, aradığınız girişi bulana (veya boş bir yer) bulana kadar anahtarı tekrar tekrar basılı tutarsınız ya da öğeyi bulana kadar bağlantılı listenizde yinelenirsiniz (veya listenin sonuna vardım)
özet
Dolayısıyla, karma tablolar anahtar / değer çiftlerini hızlı bir şekilde depolamak ve erişmek için iyi bir yoldur. Bu örnekte değer ile aynı anahtarı kullandık, ancak gerçek dünyada karma tablolarda anahtarlar çok sınırlı değil. Karma işlevleri, bir dizin oluşturmak için tuşlar üzerinde çalışır ve ardından anahtar / değer bu dizinde saklanabilir. Hash tabloları gerçekten yinelenmek için tasarlanmamıştır, ancak yapılması mümkündür. Gördüğünüz gibi, karma tabloların çok fazla boş alanı olabilir ve bunların arasında yineleme yapmak zaman kaybı olur. Karma tablo yinelemesinde boş alan aramalarını atlamak için bir mantık olsa bile, bağlantılı listeler gibi yineleyiciler için tasarlanmış bir veri yapısı kullanmak daha uygun olur.