Czerwono-Czarne Drzewa

Widziałem drzewa binarne i wyszukiwanie binarne wymienione w kilku książkach, które czytałem ostatnio, ale ponieważ jestem jeszcze na początku moich studiów w dziedzinie informatyki, muszę jeszcze wziąć udział w zajęciach, które naprawdę zajmują się algorytmami i strukturami danych w poważny sposób.

Sprawdziłem typowe źródła (Wikipedia, Google) i większość opisów przydatności i implementacji (w szczególności) Czerwono-Czarnych drzew wypadło jako gęste i trudne do zrozumienia. Na pewno za ktoś z niezbędnym tłem, to ma sens, ale w tej chwili czyta się jak język obcy prawie.

Więc co sprawia, że drzewa binarne są przydatne w niektórych typowych zadaniach, które wykonujesz podczas programowania? Poza tym, które drzewa preferujesz używać (proszę dołączyć przykładową implementację) i dlaczego?

Author: Björn Lindqvist, 2008-08-21

13 answers

Czerwone czarne drzewa są dobre do tworzenia dobrze zrównoważonych drzew. Głównym problemem z binarnymi drzewami wyszukiwania jest to, że można je bardzo łatwo zmienić w niezrównoważone. Wyobraź sobie, że twoja pierwsza liczba to 15. Następnie wszystkie liczby po tym są coraz mniejsze niż 15. Będziesz miał drzewo, które jest bardzo ciężkie po lewej stronie i nie ma nic po prawej stronie.

Czerwone Czarne drzewa rozwiązują to, zmuszając drzewo do zrównoważenia za każdym razem, gdy wstawiasz lub usuwasz. Osiąga to poprzez serię rotacje między węzłami nadrzędnymi i węzłami podrzędnymi. Algorytm jest w rzeczywistości dość prosty, chociaż jest trochę długi. Sugerowałbym zapoznanie się z podręcznikiem CLRS (Cormen, Lieserson, Rivest i Stein), "Wprowadzenie do algorytmów" i czytanie na drzewach RB.

Implementacja również nie jest tak krótka, więc prawdopodobnie nie najlepiej jest ją tutaj umieszczać. Niemniej jednak drzewa są szeroko wykorzystywane w aplikacjach o wysokiej wydajności, które wymagają dostępu do wielu danych. Oni zapewnij bardzo skuteczny sposób znajdowania węzłów, ze stosunkowo niewielkim obciążeniem wstawiania/usuwania. Ponownie, sugerowałbym spojrzeć na CLRS, aby poczytać, jak są one wykorzystywane.

Podczas gdy BST nie mogą być używane jawnie - jednym z przykładów użycia drzew w ogóle jest prawie każdy współczesny RDBM. Podobnie, Twój system plików jest prawie na pewno reprezentowany jako rodzaj struktury drzewiastej, a pliki są również indeksowane w ten sposób. Drzewa zasilają Google. Drzewa zasilają prawie każdą stronę internetową na internet.

 53
Author: FreeMemory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-11 17:43:24

Chciałbym odpowiedzieć tylko na pytanie " co sprawia, że drzewa binarne są przydatne w niektórych typowych zadaniach, które wykonujesz podczas programowania?"

To wielki temat, w którym wiele osób się nie zgadza. Niektórzy twierdzą, że algorytmy nauczane w stopniu CS, takie jak binarne drzewa wyszukiwania i wykresy kierowane, nie są używane w codziennym programowaniu i dlatego są nieistotne. Inni nie zgadzają się, twierdząc, że te algorytmy i struktury danych są podstawą dla całego naszego programowania i ważne jest, aby je zrozumieć, nawet jeśli nigdy nie musisz pisać jednego dla siebie. Filtruje to rozmowy na temat dobrych praktyk rekrutacyjnych i rekrutacyjnych. Na przykład, Steve Yegge mA artykuł nawywiad w Google , który rozwiązuje to pytanie. Pamiętajcie o tej debacie; doświadczeni ludzie się nie zgadzają.

W typowym programowaniu biznesowym może nie być konieczne tworzenie drzew binarnych lub nawet drzew bardzo często. Będziesz jednak korzystać z wielu klas, które wewnętrznie używaj drzew. Wiele podstawowych klas organizacji w każdym języku używa drzew i skrótów do przechowywania i dostępu do danych.

Jeśli jesteś zaangażowany w bardziej wydajne przedsięwzięcia lub sytuacje, które są nieco poza normą programowania biznesowego, znajdziesz drzewa, aby być bezpośrednim przyjacielem. Jak powiedział inny plakat, drzewa są podstawowymi strukturami danych dla baz danych i indeksów wszelkiego rodzaju. Są one przydatne w eksploracji danych i wizualizacji, zaawansowanej grafice (2D i 3d) oraz hosta innych problemów obliczeniowych.

Używałem drzew binarnych w postaci drzew BSP (binary space partitioning) w grafice 3d. Obecnie ponownie patrzę na drzewa, aby sortować duże ilości danych geokodowanych i innych danych do wizualizacji informacji w aplikacjach Flash/Flex. Za każdym razem, gdy przekraczasz granicę sprzętu lub chcesz działać na niższych specyfikacjach sprzętowych, zrozumienie i wybór najlepszego algorytmu może zrobić różnicę między awarią a sukces.

 18
Author: Jonathan Branam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 19:27:33

Żadna z odpowiedzi nie wspomina, do czego dokładnie służy.

Jeśli to, co chcesz zrobić, to po prostu wyszukiwanie według wartości, to hashtable jest znacznie szybsze, o(1) insert i lookup(najlepiej amortyzowane).

BST będzie o (log N), gdzie N jest liczbą węzłów w drzewie, wstawki są również O (log N).

Drzewa RB i AVL są ważne, jak inna odpowiedź wspomniana z powodu tej właściwości, jeśli zwykły BST zostanie utworzony z wartościami w kolejności, to drzewo będzie tak wysokie jako liczba wstawionych wartości jest to złe dla wydajności wyszukiwania.

Różnica między drzewami RB i AVL polega na obrotach wymaganych do zrównoważenia po wstawieniu lub usunięciu, drzewa AVL to o(log N) dla zrównoważenia, podczas gdy drzewa RB to O (1). Przykładem korzyści płynącej z tej stałej złożoności jest przypadek, w którym możesz zachować stałe źródło danych, jeśli chcesz śledzić zmiany w celu wycofania, musisz śledzić O (log N) możliwe zmiany za pomocą drzewa AVL.

Dlaczego czy byłbyś skłonny zapłacić za koszt drzewa nad stołem hash? Spokój! Tabele Hash nie mają porządku, z drugiej strony BST są zawsze naturalnie uporządkowane ze względu na ich strukturę. Więc jeśli znajdziesz się wrzucając kilka danych do tablicy lub innego kontenera, a następnie sortując je później, BST może być lepszym rozwiązaniem.

Właściwość order drzewa daje wiele możliwości iteracji uporządkowanej, in-order, depth-first, broadhth-first, pre-order, post-order. Te iteracje algorytmy są przydatne w różnych okolicznościach, jeśli chcesz je sprawdzić.

Czerwone czarne drzewa są używane wewnętrznie w prawie każdym zamówionym kontenerze bibliotek językowych, C++ Set i Map,. NET SortedDictionary, Java TreeSet itp...

Więc drzewa są bardzo przydatne i można z nich korzystać dość często nawet o tym nie wiedząc. Najprawdopodobniej nigdy nie będziesz potrzebował , aby napisać jeden samodzielnie, chociaż Gorąco polecam go jako ciekawe ćwiczenie programistyczne.

 10
Author: joshperry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-21 11:26:22

Czerwone Czarne drzewa i Drzewa B są używane we wszystkich rodzajach trwałego przechowywania; ponieważ drzewa są zrównoważone, wydajność trawersów szerokości i głębokości jest łagodzona.

Prawie wszystkie nowoczesne systemy bazodanowe używają drzew do przechowywania danych.

 4
Author: mmattax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 19:09:12

BSTs make the world go round, as said by Micheal. Jeśli szukasz dobrego drzewa do zaimplementowania, spójrz na drzewa AVL (Wikipedia). Mają warunek równoważenia, więc mają gwarancję, że będą O (logn). Ten rodzaj wydajności wyszukiwania sprawia, że logiczne jest wprowadzenie do każdego rodzaju procesu indeksowania. Jedyną rzeczą, która byłaby bardziej skuteczna, byłaby funkcja haszująca, ale te stają się brzydkie szybko, szybko i w pośpiechu. Również wpadasz na paradoks urodzinowy (także znany jako problem gołębi).

Jakiego podręcznika używasz? Wykorzystaliśmy struktury danych i analizę w Javie Marka Allena Weissa. Mam ją otwartą na kolanach, kiedy piszę to. Ma świetną sekcję o Czerwono-Czarnych drzewach, a nawet zawiera kod niezbędny do wdrożenia wszystkich drzew, o których mówi.

 2
Author: helloandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 19:12:56

Czerwono-czarne drzewa pozostają zrównoważone, więc nie musisz przemierzać głęboko, aby wydobyć przedmioty. Zaoszczędzony czas sprawia, że drzewa RB O (log () n)) w najgorszym przypadku, podczas gdy pechowe drzewa binarne mogą dostać się do konfiguracji lop i spowodować pobieranie w O (N) złym przypadku. Dzieje się tak w praktyce lub na losowych danych. Więc jeśli potrzebujesz kodu krytycznego czasu (pobieranie bazy danych, serwer sieciowy itp.) używasz drzew RB do obsługi uporządkowanych lub nieuporządkowanych list/zestawów .

Ale RBTrees są dla noobów! Jeśli jesteś robi AI i trzeba wykonać wyszukiwanie, można znaleźć widelec informacje o stanie dużo. Możesz użyć persistent red-black do rozwidlenia nowych stanów w O(log (N)). Persistent red black tree przechowuje kopię drzewa przed i po operacji morfologicznej (insert/delete), ale bez kopiowania całego drzewa (normalnie i O(log(N)) operacja). Mam otwarte drzewo Czerwono-Czarne Dla java

Http://edinburghhacklab.com/2011/07/a-java-implementation-of-persistent-red-black-trees-open-sourced/

 2
Author: Tom Larkworthy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-25 20:17:11

Najlepszy opis Czerwono-Czarnych drzew, jaki widziałem, to ten w "wstępie do algorytmów" Cormena, Leisersena i Rivesta. Mogłem go nawet zrozumieć na tyle, aby częściowo zaimplementować jeden(tylko wstawianie). Istnieje również sporo apletów, takich jak Ten na różnych stronach internetowych, które animują proces i pozwalają na oglądanie i przechodzenie przez graficzną reprezentację algorytmu budującego strukturę drzewa.

 2
Author: ConcernedOfTunbridgeWells,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-05 11:43:17

Ponieważ pytasz, którego drzewa używają ludzie, musisz wiedzieć, że czerwone czarne drzewo jest zasadniczo drzewem 2-3-4 B (tj. drzewem B rzędu 4). Drzewo B jest , a nie odpowiednikiem drzewa binarnego (jak zostało to zadane w twoim pytaniu).

Tutaj jest doskonałym źródłem opisującym początkową abstrakcję znaną jako symetryczne binarne drzewo B, które później przekształciło się w RBTree. Potrzebowałbyś dobrego zrozumienia drzew B, zanim to będzie miało sens. Podsumowując: "czerwony" link na czerwonym czarnym drzewie jest sposób na reprezentowanie węzłów, które są częścią węzła drzewa B (wartości w zakresie klucza), podczas gdy "Czarne" linki są węzłami, które są połączone pionowo w drzewie B.

Oto, co otrzymujesz, tłumacząc Zasady czerwonego czarnego drzewa w kategoriach drzewa B (używam formatu reguły czerwonego czarnego drzewa => odpowiednik drzewa B):

1) węzeł jest czerwony lub czarny. = > Węzeł w drzewie b może być częścią węzła lub jako węzeł na nowym poziomie.

2) korzeń jest czarny. (Ta reguła jest czasami pomijana, ponieważ nie wpływa na analizę) = > węzeł główny może być traktowany albo jako część wewnętrznego węzła głównego, jako dziecko wyimaginowanego węzła nadrzędnego.

3) wszystkie liście (ZERO) są czarne. (Wszystkie liście są tego samego koloru co korzeń.) = > Ponieważ jednym ze sposobów reprezentowania drzewa RB jest pomijanie liści, możemy to wykluczyć.

4) oba dzieci każdego czerwonego węzła są czarne. = > Dzieci wewnętrznego węzła w drzewie B zawsze leżą na innym poziom.

5) każda prosta ścieżka od danego węzła do dowolnego z jego liści potomnych zawiera tę samą liczbę czarnych węzłów. Drzewo B jest utrzymywane w równowadze, ponieważ wymaga, aby wszystkie węzły liści znajdowały się na tej samej głębokości (stąd wysokość węzła drzewa B jest reprezentowana przez liczbę czarnych ogniw od korzenia do liścia czerwonego czarnego drzewa)

Istnieje również prostsza "niestandardowa" implementacja Roberta Sedgewicka tutaj: (jest autorem książki algorytmy wraz z Wayne ' em)

 1
Author: arviman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-17 14:03:25

Dużo, dużo ciepła tutaj, ale nie dużo światła, więc zobaczmy, czy możemy zapewnić trochę.

Po pierwsze, drzewo RB jest asocjacyjną strukturą danych, w przeciwieństwie do, powiedzmy tablicy, która nie może przyjąć klucza i zwrócić powiązanej wartości, chyba że jest to liczba całkowita "klucz" w 0% rzadkim indeksie sąsiednich liczb całkowitych. Tablica też nie może rosnąć (tak, Wiem o realloc (), ale pod pokrywami, które wymagają nowej tablicy, a następnie memcpy ()), więc jeśli masz jedną z tych wymagania, tablica nie wystarczy. Wydajność pamięci tablicy jest doskonała. Zero waste, ale niezbyt inteligentne i elastyczne-realloc () nie wytrzymuje.

Drugie, w przeciwieństwie do bsearch() na tablicy elementów, która jest asocjacyjną strukturą danych, drzewo RB może dynamicznie rosnąć (i kurczyć się). Bsearch () działa dobrze do indeksowania struktury danych o znanym rozmiarze, która pozostanie tą wielkością. Więc jeśli nie znasz z góry rozmiaru swoich danych lub nowych elementy muszą być dodane lub usunięte, bsearch () nie działa. Bsearch () i qsort() są dobrze obsługiwane w klasycznym C i mają dobrą wydajność pamięci, ale nie są wystarczająco dynamiczne dla wielu aplikacji. Są one jednak moim ulubionym, ponieważ są szybkie, łatwe, a jeśli nie masz do czynienia z aplikacjami w czasie rzeczywistym, często są wystarczająco elastyczne. Ponadto w C / C++ można posortować tablicę wskaźników do rekordów danych, wskazując na element struc {}, na przykład, który chcesz porównać, a następnie przestawianie wskaźnika w tablicy wskaźników w taki sposób, że odczyt wskaźników w kolejności na końcu sortowania wskaźnika daje dane w kolejności posortowanej. Używanie tego z plikami danych mapowanych w pamięci jest niezwykle wydajne, szybkie i dość łatwe. Wszystko, co musisz zrobić, to dodać kilka "*"do funkcji porównywania.

Po Trzecie, w przeciwieństwie do hashtable, który również musi mieć stały rozmiar i nie może być uprawiany Po wypełnieniu, drzewo RB automatycznie rośnie i równoważy się do utrzymać gwarancję wydajności O (log (n)). Szczególnie jeśli kluczem drzewa RB jest int, może być on szybszy niż hash, ponieważ nawet jeśli złożoność hashtable wynosi O(1), to 1 może być bardzo kosztownym obliczaniem hash. Wielokrotne 1-zegarowe liczby całkowite drzewa często przewyższają 100-zegarowe+ obliczenia hash, nie mówiąc już o ponownym przetwarzaniu, a malloc()ING space dla kolizji i ponownych obliczeń. Wreszcie, jeśli chcesz uzyskać dostęp do ISAM, a także kluczowy dostęp do danych, Hash jest wykluczony, ponieważ tam czy kolejność danych nie jest związana z hashtable, w przeciwieństwie do naturalnej kolejności danych w dowolnej implementacji drzewa. Klasyczne użycie tabeli skrótów polega na zapewnieniu dostępu do tabeli słów kluczowych dla kompilatora. Jego wydajność pamięci jest doskonała.

Czwarta , bardzo nisko na dowolnej liście, jest listą linkowaną lub podwójnie linkowaną, która w przeciwieństwie do tablicy, w naturalny sposób obsługuje wstawianie i usuwanie elementów, a co za tym idzie, zmianę rozmiaru. To najwolniejszy z wszystkie struktury danych, ponieważ każdy element wie tylko jak dostać się do następnego elementu, więc musisz przeszukiwać średnio (element_knt/2) Linki, aby znaleźć swoje dane. Jest on najczęściej używany tam, gdzie wstawianie i usuwanie gdzieś w środku listy są powszechne, a zwłaszcza, gdy lista jest okrągła i karmi drogi proces, który sprawia, że czas na czytanie linków jest stosunkowo mały. Moim ogólnym RX jest użycie arbitralnie dużej tablicy zamiast połączonej listy, jeśli jedynym wymogiem jest to, że jest w stanie zwiększyć rozmiar. Jeśli zabraknie rozmiaru tablicy, możesz realloc() większą tablicę. STL robi to za ciebie "pod pokrywami", gdy używasz wektora. Surowy, ale potencjalnie 1000 s razy szybszy, jeśli nie potrzebujesz wstawiania, usuwania lub wyszukiwania z kluczem. Jego wydajność pamięci jest słaba, szczególnie w przypadku list podwójnie połączonych. W rzeczywistości podwójnie powiązana lista, wymagająca dwóch wskaźników, jest dokładnie tak samo nieefektywna jak czerwono-czarne drzewo, a jednocześnie nie ma żadnego atrakcyjnego szybkiego, uporządkowane właściwości odzyskiwania.

Po piąte, drzewa obsługują wiele dodatkowych operacji na swoich posortowanych danych niż jakakolwiek inna struktura danych. Na przykład wiele zapytań bazodanowych wykorzystuje fakt, że zakres wartości liści można łatwo określić, określając ich wspólny rodzic, a następnie koncentrując późniejsze przetwarzanie Na części drzewa, które rodzic "posiada". Potencjał wielowątkowości oferowany przez to podejście powinien być oczywisty, ponieważ tylko niewielki obszar drzewa musi być zablokowany-mianowicie tylko węzły, które posiada rodzic i sam rodzic.

W skrócie, drzewa są Cadillac struktur danych. Płacisz wysoką cenę pod względem używanej pamięci, ale otrzymujesz całkowicie samo-utrzymującą się strukturę danych. Z tego powodu, jak podkreślono w innych odpowiedziach, bazy danych transakcji używają niemal wyłącznie drzew.

 1
Author: user2548100,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-19 23:54:09

Jeśli chcielibyście zobaczyć jak powinno wyglądać czerwono-czarne drzewo, kodowałem implementację Czerwono-czarnego drzewa, którą możecie pobrać tutaj

 0
Author: Brock Woolf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-08 16:06:36

IME, prawie nikt nie rozumie algorytmu drzewa RB. Ludzie mogą powtarzać ci zasady, ale nie rozumieją dlaczego i skąd pochodzą. Nie jestem wyjątkiem: -)

Z tego powodu wolę algorytm AVL, ponieważ łatwo jest zrozumieć . Kiedy to zrozumiesz, możesz go zakodować od zera, ponieważ ma to dla ciebie sens.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-24 21:04:04

Drzewa potrafią być szybkie. Jeśli masz milion węzłów w zrównoważonym drzewie binarnym, znalezienie dowolnego elementu zajmuje średnio dwadzieścia porównań. Jeśli masz milion węzłów na połączonej liście, znalezienie tego samego elementu zajmuje średnio pięćset tysięcy porównań.

Jeśli drzewo jest niezrównoważone, może być tak samo wolne jak Lista, i również zajmują więcej pamięci do przechowywania. Wyobraź sobie drzewo, w którym większość węzłów ma prawe dziecko, ale nie lewe; to jest listą, ale ty nadal trzeba trzymać miejsce w pamięci, aby umieścić w lewym węźle, jeśli się pojawi.

W każdym razie, drzewo AVL było pierwszym zrównoważonym algorytmem drzewa binarnego, a artykuł o nim w Wikipedii jest dość jasny. Artykuł na Wikipedii o czerwono-czarnych drzewach jest czysty jak błoto, szczerze.

Poza drzewami binarnymi, drzewa B są drzewami, w których każdy węzeł może mieć wiele wartości. B-Tree to NIE drzewo binarne, tak się składa, że to jego nazwa. Są naprawdę przydatne do wykorzystania pamięci wydajnie; każdy węzeł drzewa może być wielkości, aby zmieścić się w jednym bloku pamięci, tak, że nie jesteś (powoli) idzie i znaleźć mnóstwo różnych rzeczy w pamięci, które zostały paged do dysku. Oto fenomenalny przykład B-Tree.

 0
Author: Dean J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-09 19:57:41

Jeśli chcesz rzucić okiem na moją realizację Red Black Tree. http://code.google.com/p/cstl/source/browse/src/c_rb.c

 0
Author: Avinash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-12 13:35:22