İsim-Değer Çiftleri ile Arama İşlevi
Önceki IX. Oylum - Arama ve Sıralama Sonraki
İsim-Değer Çiftleri ile Arama İşlevi
Bu kısma gelinceye kadar sıralı ve sırasız dizilerde arama yapılmasından bahsedildi. Bilgileri aramadan önce düzenlemek için başka yöntemler de vardır. Bilgi girme, silme ve arama maliyetleri farklıdır. Olası bir gerçekleme de isim-değer çiftleri tablosu (hashing table) kullanmaktır. Bu kısımda bahsedilecek işlevler search.h başlık dosyasında bildirilmiştir.
int hcreate
(size_t sayı)
işlev
hcreate işlevi en az sayı eleman içeren bir isim-değer çifti tablosu oluşturur. Bu tabloyu daha sonra genişletmek mümkün olmadığından eleman sayısı akıllıca seçilmelidir. Bu işlevi gerçeklemekte kullanılan yöntem tablodaki eleman sayısının kullanılması olası en büyük eleman sayısından daha büyük olarak belirlenmesini gerektirir. %80’den fazlası dolu olan isim-değer çifti tabloları çalışmak için yetersiz olur. Yöntem tarafından garanti edilen sabit erişim süresine bir kaç çakışma mevcut olduğunda ulaşılabilir. Bu konuda daha fazla bilgi isterseniz Knuth'un "The Art of Computer Programming, Part 3: Searching and Sorting" adlı eserine bakınız.
Bu işlevin en zayıf tarafı bir yazılım için en çok bir tablonun olabilmesidir. Tablo yazılımcının denetimi dışında yerel bellek bölgesinde oluşturulur. GNU C kütüphanesi, bu arayüze benzeyen ve çok sayıda tablonun tutulmasını mümkün kılan evresel (reentrant) bir arayüz ile çalışan ek işlevlere de sahiptir.
Bir yazılım içinde birden fazla isim-değer çifti tablosu kullanımı, biçimsel tablonun bir hdestroy çağrısı ile kaldırılmasından sonra mümkün olur.
Tablo başarıyla oluşturulmuşsa işlev sıfırdan farklı bir değerle döner. Aksi takdirde ya zaten kullanılan bir tablo vardır ya da yazılım yetersiz bellekle çalışıyordur ki, bu durumda işlev sıfır değeriyle döner.
void hdestroy
(void)
işlev
hdestroy işlevi daha önceki bir hcreate çağrısı ile ayrılan özkaynakları serbest bırakmak için kullanılabilir. Bu işlev çağrıldıktan sonra tekrar bir hcreate çağrısı yapabilmek ve farklı boyutta bir tablo oluşturmak mümkün olur.
Önemli
hdestroy çağrısı sırasında tablo içindeki elemanlar bu işlev tarafından serbest bırakılmaz. Bu, dizgeleri serbest bırakacak yazılım kodunun sorumluluğudur. Tabloda mevcut tüm elemanlarla tek tek uğraşacak bir işlev olmadığından bellekteki elemanların tümünün serbest bırakılması mümkün değildir. Tablo ve tablo içindeki tüm elemanların serbest bırakılması önemliyse, yazılımcı tablo elemanlarının bir listesini tutmalı ve hdestroy çağrısından önce bu listeyi kullanarak tüm elemanların verilerini serbest bırakmalıdır. Bu çok tatsız bir mekanizmadır ve isim-değer çifti tablolarının bu türünün yazılım tarafından bir kere oluşturulup, yazılım sonlandırılıncaya kadar kullanılacağını gösterir.
Arama işleminin yapılacağı isim-değer çiftleri aşağıdaki veri türü ile oluşturulur:
struct ENTRY
veri türü
Bu yapının her iki elemanı da boş karakter sonlandırmalı dizge göstericisidir. Bu durum hsearch işlevlerinin işlevselliğinin sınırlarını belirler. Sadece boş karakter ile sonlandırılabilen verilerle çalışılabilir, genel ikilik verilerle çalışabilmek mümkün değildir.
char *key
Tablo içindeki elemanı ifade eden ya da arama anahtarı olarak kullanılacak olan boş karakter sonlandırmalı dizgenin göstericisidir (çiftin isim parçası).
char *data
Çiftin değer parçasını oluşturan boş karakter sonlandırmalı dizgenin göstericisidir. İşlevler sadece bir mevcut girdiyi aramak için kullanılırsa, bu eleman kullanılmadığından tanımsız kalabilir.
ENTRY *hsearch
(ENTRY  girdi,
 ACTION eylem)
işlev
Bir isim değer çifti tablosunda arama yapmak için hcreate işleviyle oluşturulan tabloda arama yapmak için hsearch işlevi kullanılmalıdır. Bu işlev ya (eylem değeri olarak FIND verilmişse) bir elemanı aramakta ya da tabloya yeni bir isim elemanı girmekte kullanılır. Girdiler değiştirilemez.
Yapının isim elemanını oluşturan key elemanı ENTRY türünde bir nesnenin göstericisidir. Bir tablo üzerindeki bir girdiyi konumlamak için yapının key elemanı kullanılır.
key ile eşleşen bir girdinin varlığı durumunda eylem yoksayılır. Bulunan girdi döner. Bir eşleşme bulunamazsa ve eylem değeri FIND ise işlev boş gösterici ile döner. Bir eşleşme bulunamazsa ve eylem değeri ENTER ise girdi ile ilklendirilerek tabloya yeni bir girdi eklenir ve işlev eklenen girdinin göstericisi ile döner.
Şimdiye dek bahsedilen işlevler geneldir ve yazılımda bir defada en çok bir isim-değer çifti tablosunun varolabildiği durumda kullanılabilirler. Bunun tersi durumlarda bir GNU oluşumu olarak aşağıdaki işlevler kullanılabilir. Bu işlevler struct hsearch_data türünde nesnelerden oluşan bir isim-değer çifti tablosu ile çalışır. Bu veri türü şeffaf değildir, yani üyeleri doğrudan değişirilemez.
int hcreate_r
(size_t               sayı,
 struct hsearch_data *tablo)
işlev
hcreate_r işlevi en az sayı eleman içeren tablo isimli isim-değer çiftleri tablosunu ilklendirir. Bu işlev, yazılımcı tarafından denetlenebilir bir tablo oluşturmak dışında hcreate işlevi gibidir.
Bu işlev bir defada birden fazla isim-değer çiftleri tablosu oluşturulabilmesini mümkün kılar. struct hsearch_data nesnesi için gereken bellek özdevimli ayrılabilir ancak bu işlevi çağırmadan önce sıfırla doldurularak ilklendirilmelidir.
İşlem başarılıysa işlev sıfırdan farklı bir değerle döner. Sıfır değeri dönmüşse ya birşeyler yanlış gitmiştir ya da yazılım yetersiz bellekle çalışıyordur.
void hdestroy_r
(struct hsearch_data *tablo)
işlev
hdestroy_r işlevi hcreate_r işlevi ile oluşturulan tablo tablosu tarafından kullanılan tüm kaynakları serbest bırakır. Tablonun içindeki elemanların serbest bırakılması bakımından hdestroy gibidir.
int hsearch_r
(ENTRY                girdi,
 ACTION               eylem,
 ENTRY              **dönüşdeğeri,
 struct hsearch_data *tablo)
işlev
hsearch_r işlevi hsearch işlevine eşdeğerdir. İlk iki argüman aynıdır. Ancak tek bir genel tablo yerine hcreate_r işlevi ile ilklendirilen ve tablo ile gösterilen bir tablo ile çalışır.
hcreate işlevinden diğer bir farkı da tabloda bulunan değeri işlevin dönüş değeri olarak değil, dönüşdeğeri parametresi tarafından gösterilen bir gösterici değişkeni içinde döndürmesidir. İşlevin geri dönüş değeri işlev başarılı ise sıfırdan farklı, değilse sıfırdır. errno genel değişkeni başarısızlığın sebebini gösterir:
ENOMEM
Tablo doludur, hsearch_r işlevi eylem değeri olarak ENTER belirtilerek, bilinmeyen bir girdi ile çağrılmıştır.
ESRCH
eylem parametresi olarak FIND belirtilmiş ve tabloda belirtilen girdi bulunamamıştır.
Önceki Üst Ana Başlık Sonraki
Arama ve Sıralama Örneği Başlangıç Ağaç Arama İşlevi
Bir Linux Kitaplığı Sayfası