Poprzednie odpowiedzi dotyczyły tylko alternatyw drzewa, a czerwony czarny prawdopodobnie pozostaje tylko z powodów historycznych.
Dlaczego nie tablica skrótów?
Typ wymaga tylko <
operatora (porównania) do użycia jako klucza w drzewie. Jednak tabele skrótów wymagają, aby każdy typ klucza miał hash
zdefiniowaną funkcję. Ograniczenie wymagań dotyczących typu do minimum jest bardzo ważne dla programowania ogólnego, dzięki czemu można go używać z szeroką gamą typów i algorytmów.
Projektowanie dobrej tabeli skrótów wymaga dogłębnej znajomości kontekstu, w którym będzie używana. Czy powinien używać otwartego adresowania, czy łączenia łańcuchowego? Jakie poziomy obciążenia powinien zaakceptować przed zmianą rozmiaru? Czy powinien używać drogiego skrótu, który pozwala uniknąć kolizji, czy takiego, który jest szorstki i szybki?
Ponieważ STL nie może przewidzieć, który jest najlepszy wybór dla Twojej aplikacji, domyślna musi być bardziej elastyczna. Drzewa „po prostu działają” i dobrze się skalują.
(C ++ 11 dodał tabele skrótów unordered_map
. Z dokumentacji wynika, że wymaga to ustawienia zasad, aby skonfigurować wiele z tych opcji).
Co z innymi drzewami?
Drzewa Red Black oferują szybkie wyszukiwanie i same się równoważą, w przeciwieństwie do BST. Inny użytkownik zwrócił uwagę na jego zalety w stosunku do samowyważącego się drzewa AVL.
Alexander Stepanov (twórca STL) powiedział, że użyłby drzewa B * zamiast drzewa czerwono-czarnego, gdyby napisał std::map
ponownie, ponieważ jest bardziej przyjazny dla nowoczesnych pamięci podręcznych.
Jedną z największych zmian od tego czasu był wzrost pamięci podręcznych. Błędy w pamięci podręcznej są bardzo kosztowne, więc lokalizacja odniesienia jest teraz o wiele ważniejsza. Struktury danych oparte na węzłach, które mają małą lokalizację odniesienia, mają znacznie mniej sensu. Gdybym dzisiaj projektował STL, miałbym inny zestaw pojemników. Na przykład drzewo B * w pamięci jest znacznie lepszym wyborem niż drzewo czerwono-czarne do implementacji kontenera asocjacyjnego. - Alexander Stepanov
Czy mapy powinny zawsze używać drzew?
Inną możliwą implementacją map byłby posortowany wektor (sortowanie wstawiane) i wyszukiwanie binarne. Działa to dobrze w przypadku kontenerów, które nie są często modyfikowane, ale są często pytane. Często robię to w C qsort
i bsearch
są wbudowane.
Czy muszę nawet korzystać z mapy?
Rozważania cache oznacza, że rzadko ma sens użycie std::list
lub std::deque
nad std:vector
nawet dla tych sytuacjach, uczono nas w szkole (takie jak usunięcie elementu ze środka listy). Stosując to samo rozumowanie, użycie pętli for do wyszukiwania liniowego listy jest często bardziej wydajne i czystsze niż budowanie mapy dla kilku wyszukiwań.
Oczywiście wybór czytelnego pojemnika jest zwykle ważniejszy niż wydajność.