Önceki cevaplar sadece ağaç alternatiflerini ele alır ve kırmızı siyah muhtemelen sadece tarihsel nedenlerle kalır.
Neden karma tablo yok?
Bir tür, yalnızca <
işlecin (karşılaştırma) ağaçta anahtar olarak kullanılmasını gerektirir . Ancak, karma tablolar her anahtar türünün hash
tanımlanmış bir işleve sahip olmasını gerektirir . Çok çeşitli tür ve algoritmalarla kullanabilmeniz için genel programlama için tür gereksinimlerini minimumda tutmak çok önemlidir.
İyi bir karma tablo tasarlamak, kullanılacağı bağlam hakkında derinlemesine bilgi gerektirir. Açık adresleme mi yoksa bağlantılı zincirleme mi kullanmalı? Yeniden boyutlandırmadan önce hangi yük seviyelerini kabul etmelidir? Çarpışmalardan kaçınan pahalı bir karma mı yoksa kaba ve hızlı bir karma mı kullanmalı?
STL, uygulamanız için en iyi seçim olanı tahmin edemediğinden, varsayılanın daha esnek olması gerekir. Ağaçlar "sadece çalışır" ve güzel ölçeklenir.
(C ++ 11 ile karma tablolar ekledi unordered_map
. Bu seçeneklerin birçoğunu yapılandırmak için ilkelerin ayarlanmasını gerektiren belgelerden görebilirsiniz .)
Peki ya diğer ağaçlar?
Kırmızı Siyah ağaçlar, BST'lerin aksine hızlı arama sunar ve kendi kendini dengeliyor. Başka bir kullanıcı, kendi kendini dengeleyen AVL ağacı üzerindeki avantajlarına dikkat çekti.
Alexander Stepanov (STL'nin yaratıcısı), std::map
tekrar yazdığı takdirde Kırmızı-Siyah ağaç yerine B * Ağacı kullanacağını söyledi , çünkü modern bellek önbellekleri için daha dostudur.
O zamandan bu yana yapılan en büyük değişikliklerden biri önbelleklerin büyümesi oldu. Önbellek özledikleri çok maliyetlidir, bu nedenle referans yeri artık çok daha önemlidir. Referans konumu düşük olan düğüm tabanlı veri yapıları çok daha az mantıklıdır. Bugün STL tasarlayacak olsaydım, farklı bir konteyner setim olurdu. Örneğin, bellek içi bir B * ağacı, bir ilişkisel kap uygulamak için kırmızı-siyah bir ağaçtan çok daha iyi bir seçimdir. - Alexander Stepanov
Haritalar her zaman ağaç kullanmalı mı?
Başka bir olası harita uygulaması, sıralı bir vektör (ekleme sıralaması) ve ikili arama olacaktır. Bu, sık sık değiştirilmeyen ancak sık sık sorgulanan kaplar için iyi çalışır. Bunu genellikle C olarak qsort
ve bsearch
yerleşik olarak yaparım .
Haritayı kullanmam bile gerekiyor mu?
Önbellek değerlendirmeleri, nadiren std::list
veya daha std::deque
fazla kullanımın mantıklı olduğu anlamına gelirstd:vector
, okulda bize öğretilen bu durumlar için bile (listenin ortasından bir öğenin kaldırılması gibi) . Aynı akıl yürütmeyi uygulamak, bir listeyi doğrusal aramaya kullanmak için for döngüsü kullanmak, birkaç arama için bir harita oluşturmaktan genellikle daha verimli ve daha temizdir.
Tabii ki okunabilir bir kap seçmek genellikle performanstan daha önemlidir.