Hashing Nedir?
Hashing, verileri belirli bir algoritma ile sabit uzunlukta bir değere dönüştürme işlemidir. Bu dönüşüm, veri yapılarında hızlı erişim, güvenlik ve bütünlük sağlamak amacıyla kullanılır. Hash fonksiyonları, girdiyi işleyerek belirli bir uzunlukta hash değeri (karma değeri) üretir. Hashing, özellikle veri tabanları, kriptografi, arama algoritmaları ve veri bütünlüğü doğrulama işlemlerinde önemli bir rol oynar.
Hash Fonksiyonları
Bir hash fonksiyonu, girdiyi belirli matematiksel işlemlerden geçirerek sabit uzunlukta bir çıktı üretir. Etkili bir hash fonksiyonunun sahip olması gereken temel özellikler şunlardır:
- Deterministik Olma: Aynı girdiye her zaman aynı çıktıyı üretmelidir.
- Hızlı Hesaplanabilirlik: Büyük veri kümelerinde dahi hızlı bir şekilde hesaplanmalıdır.
- Çakışma (Collision) Azaltma: Farklı girdiler için aynı hash değerini üretme olasılığı düşük olmalıdır.
- Dağıtım Dengesi: Hash değerleri mümkün olduğunca rastgele dağılmalı, kümelenme olmamalıdır.
HashSet ve HashMap
HashSet ve HashMap, hashing mantığı ile çalışan veri yapılarıdır ve genellikle veri saklama ve erişim işlemlerinde kullanılır.
HashSet (Unordered_Set)
HashSet, benzersiz elemanları saklamak için kullanılan bir veri yapısıdır. Veri ekleme, silme ve arama işlemlerini ortalama O(1) zaman karmaşıklığıyla gerçekleştirir. HashSet'in temel özellikleri şunlardır:
- Tekrarsız Eleman Saklama: Aynı elemandan yalnızca bir tane bulunur.
- Sırasız Veri Yapısı: Elemanlar belirli bir düzene göre saklanmaz.
- Hızlı Arama: İçerdiği öğelere doğrudan erişim sağlar.
C++ ile HashSet Fonksiyonları Kullanımı (Kütüphane: unordered_set)
#includeusing namespace std; int main() { // String veri tipinde değerler saklamak için unordered_set tanımlanıyor unordered_set stringSet; // Farklı string değerler ekleniyor, aynı değer birden fazla kez eklenirse yalnızca bir kez saklanır stringSet.insert("Istanbul"); stringSet.insert("Ankara"); stringSet.insert("Kars"); stringSet.insert("T3"); stringSet.insert("Istanbul"); // Aranacak anahtar (key) tanımlanıyor string key = "Izmir"; // find() fonksiyonu, eğer aranan anahtar bulunamazsa end() iterator'ünü döndürür // Eğer anahtar bulunursa, ona karşılık gelen iterator döndürülür if (stringSet.find(key) == stringSet.end()) cout << key << " bulunamadi" << endl << endl; else cout << " Bulundu" << key << endl << endl; // key değeri güncelleniyor key = "T3"; if (stringSet.find(key) == stringSet.end()) cout << key << " Bulunamadi\n"; else cout << "Bulundu" << key << endl; // Şimdi tüm set elemanlarını ekrana yazdırıyoruz cout << "\nTum elemanlar : "; unordered_set ::iterator iter; for (iter = stringSet.begin(); iter != stringSet.end(); iter++) cout << (*iter) << endl; }
HashMap (Unordered_Map)
HashMap, anahtar-değer çiftlerini saklayan ve anahtar üzerinden hızlı erişim sağlayan bir veri yapısıdır. HashMap'in özellikleri şu şekildedir:
- Anahtar-Değer (Key-Value) İlişkisi: Verilere anahtarlar aracılığıyla erişilir.
- Hızlı Erişim: Anahtara bağlı olarak değerler hızlı bir şekilde çağrılabilir.
- Çakışma (Collision) Yönetimi: Aynı hash değerine sahip anahtarlar farklı kovalar (buckets) kullanılarak saklanır.
C++ ile HashMap Fonksiyonları Kullanımı (Kütüphane: unordered_map)
#includeusing namespace std; int main() { // Anahtar-değer çiftleri saklamak için unordered_map tanımlanıyor unordered_map dictionary; // Farklı kelimeler ve anlamları ekleniyor dictionary["apple"] = "elma"; dictionary["banana"] = "muz"; dictionary["cherry"] = "kiraz"; dictionary["date"] = "hurma"; dictionary["fig"] = "incir"; // Aranacak kelime belirleniyor string key = "banana"; // find() fonksiyonu, eğer anahtar bulunamazsa end() iterator'ünü döndürür // Eğer anahtar bulunursa, karşılık gelen anlamı ekrana yazdırılır if (dictionary.find(key) == dictionary.end()) cout << key << " sözlükte bulunamadı" << endl << endl; else cout << key << " kelimesinin anlamı: " << dictionary[key] << endl << endl; // Şimdi tüm sözlük elemanlarını ekrana yazdırıyoruz cout << "Sözlükteki tüm kelimeler ve anlamları:" << endl; for (const auto &pair : dictionary) cout << pair.first << " -> " << pair.second << endl; // Kovalar ile ilgili bilgiler cout << "\nKovalar ve içerdikleri elemanlar:" << endl; for (size_t i = 0; i < dictionary.bucket_count(); i++) { cout << "Kova " << i << ": "; for (auto it = dictionary.begin(i); it != dictionary.end(i); ++it) { cout << "(" << it->first << " -> " << it->second << ") "; } cout << endl; } return 0; }
Hashing Kullanım Alanları
Hashing, birçok farklı alanda kullanılan temel bir tekniktir:
- Veri Tabanları: Hızlı veri erişimi ve indeksleme sağlar.
- Kriptografi: Veri bütünlüğünü ve güvenliğini sağlamak için kullanılır (örn. SHA-256).
- Dosya Sistemleri: Büyük veri kümelerinde dosya arama işlemlerini hızlandırır.
- Bellek Yönetimi: Önbellek mekanizmalarında veri saklama ve getirme süreçlerini optimize eder.