Wygląda na to, że gdziekolwiek spojrzę, struktury danych są wdrażane przy użyciu czerwono-czarnych drzew ( std::set
w C ++, SortedDictionary
w C # itp.)
Właśnie omawiając (a, b), czerwono-czarne i drzewa AVL w mojej klasie algorytmów, oto co wyciągnąłem (również z pytania po profesorach, przeglądania kilku książek i przeglądania go trochę):
- Drzewa AVL mają mniejszą średnią głębokość niż drzewa czerwono-czarne, dlatego wyszukiwanie wartości w drzewie AVL jest konsekwentnie szybsze.
- Drzewa czerwono-czarne wprowadzają mniej zmian strukturalnych w celu zrównoważenia się niż drzewa AVL, co może potencjalnie przyspieszyć ich wstawianie / usuwanie. Mówię potencjalnie, ponieważ będzie to zależeć od kosztu zmiany strukturalnej drzewa, ponieważ będzie to w dużej mierze zależeć od środowiska wykonawczego i implementacji (może być zupełnie inaczej w funkcjonalnym języku, gdy drzewo jest niezmienne?)
Istnieje wiele testów porównawczych online, które porównują drzewa AVL i czerwono-czarne, ale uderzyło mnie to, że mój profesor w zasadzie powiedział, że zwykle zrobiłbyś jedną z dwóch rzeczy:
- Albo tak naprawdę nie zależy ci na wydajności, w takim przypadku różnica 10-20% AVL w porównaniu z czerwono-czarną w większości przypadków nie będzie miała żadnego znaczenia.
- Lub naprawdę zależy Ci na wydajności, w którym to przypadku porzucisz zarówno drzewa AVL, jak i czerwono-czarne, i wybierzesz drzewa B, które można dostosować, aby działały znacznie lepiej (lub (a, b) -tree, ja ” włożę wszystkie do jednego koszyka.)
Powodem tego jest to, że B-drzewo przechowuje dane bardziej zwięźle w pamięci (jeden węzeł zawiera wiele wartości), będzie znacznie mniej braków pamięci podręcznej. Możesz również dostosować implementację w zależności od przypadku użycia i uzależnić kolejność B-drzewa od wielkości pamięci podręcznej procesora itp.
Problem polega na tym, że nie mogę znaleźć prawie żadnego źródła, które analizowałoby rzeczywiste użycie różnych implementacji drzew wyszukiwania na prawdziwym nowoczesnym sprzęcie. Przejrzałem wiele książek na temat algorytmów i nie znalazłem niczego, co porównywałoby różne warianty drzew, oprócz pokazania, że jedna ma mniejszą średnią głębokość niż druga (co tak naprawdę nie mówi zbyt wiele o zachowaniu drzewa w prawdziwych programach).
Biorąc to pod uwagę, czy jest jakiś szczególny powód, dla którego wszędzie stosuje się czerwono-czarne drzewa, gdy w oparciu o to, co powiedziano powyżej, B-drzewa powinny być lepsze od nich? (jako jedyny test, jaki mogłem znaleźć, pokazuje również http://lh3lh3.users.sourceforge.net/udb.shtml , ale może to być tylko kwestia konkretnej implementacji). A może powód, dla którego wszyscy używają czerwono-czarnych drzew, ponieważ są one dość łatwe do wdrożenia lub, innymi słowy, trudne do wdrożenia źle?
Jak to się zmieni, gdy przejdziemy do dziedziny języków funkcjonalnych? Wygląda na to, że zarówno Clojure, jak i Scala używają mapowanych tablic Hash , w których Clojure stosuje współczynnik rozgałęzienia wynoszący 32.