Miért std :: map végre egy piros-fekete fa ?
Számos kiegyensúlyozott bináris keresés fák (BSTs) odakint. Mik voltak kialakítás kompromisszumok kiválasztásában piros-fekete fa?
Miért std :: map végre egy piros-fekete fa ?
Számos kiegyensúlyozott bináris keresés fák (BSTs) odakint. Mik voltak kialakítás kompromisszumok kiválasztásában piros-fekete fa?
Valószínűleg a két leggyakoribb önkiegyensúlyozást fa algoritmusok Piros-fekete fák és az AVL fák . Az egyensúly a fa után behelyezése / frissítés mindkét algoritmus használ a fogalom forgatások, ahol a fa csomópontjait forgatjuk, hogy végre a kiegyensúlyozatlanság.
Míg mindkét algoritmus a beszúrás / törlés művelet O (log n), abban az esetben a piros-fekete fa újra egyensúlyba forgatás egy O (1) működés közben a AVL ez egy O (log n) műveletet, így a piros-fekete fa hatékonyabb ebből a szempontból az újbóli egyensúlyba szakaszában és az egyik lehetséges oka, hogy gyakrabban használják.
Piros-fekete fák használják a legtöbb gyűjtemény könyvtárak, beleértve a kínálatát a Java és a Microsoft .NET-keretrendszer.
Ez csak a választás az Ön végrehajtás - ők is meg lehet valósítani, mint bármely kiegyensúlyozott fa. A különböző választási lehetőségek összes hasonló kisebb eltérésekkel. Ezért minden olyan jó, mint bármelyik másik.
AVL fák maximális magassága 1.44logn, míg RB fák maximum 2logn. Behelyezése Elem AVL járhat, újrakiegyenlítő egy ponton a fán. A kiegyensúlyozás befejezi a behelyezés. Behelyezése után egy új levél, frissítése az ősei, hogy levél kell tenni akár a gyökér, vagy akár egy pont, ahol a két részfák egyenlő mélységben. Annak a valószínűsége, amelyek a frissítés, k csomópont is 1/3 ^ k. Kiegyensúlyozás O (1). Eltávolítása elem jelenti egynél több kiegyensúlyozás (akár a fele a fa mélysége).
RB-fák B-fák érdekében 4 binárisan keresési fák. A 4-csomópont a B-fa eredményeket két szinten a egyenértékű BST. A legrosszabb esetben az összes fa csomópontjait 2-csomópontok, csak egy lánc 3-csomópont le egy levél. Ez levél lesz a parttól 2logn a gyökér.
Lement a tövétől a beszúrási pontot, az egyik, hogy változtatni 4-csomópontokat 2-csomópontok, így biztosítva, hogy behelyezés nem telíti a levél. Visszatérve a feltöltés, mind a csomópontok elemezni kell, hogy megbizonyosodjon arról, hogy helyesen képviseli 4-csomópontokat. Ezt is el lehet végezni lement a fán. A globális költség ugyanaz lesz. Nincs ingyen ebéd! Eltávolítása elemet a fa azonos nagyságrendű.
Mindezek a fáknak, hogy csomópontok olyan információt magasság, súly, szín, stb Csak ferde fák mentesek az ilyen kiegészítő info. De a legtöbb ember fél a ferde fákat, mert a ramdomness szerkezetük!
Végül a fák is súlya információt a csomópontok, amelyek lehetővé teszik plusz súlya. Különböző rendszereket lehet alkalmazni. Meg kell újra egyensúlyba amikor részfa több mint 3-szor az elemek száma a többi részfa. Vegetarian ismét történhet throuh egy szimpla vagy dupla forgatás. Ez azt jelenti, legrosszabb esetben 2.4logn. Egy megúszni 2-szer 3 helyett, sokkal jobb az arány, de azt is jelentheti, így egy kicsit kevesebb Thant 1% részfák kiegyensúlyozatlan itt-ott. Furfangos!
Milyen típusú fa van a legjobb? AVL, az biztos. Ezek a legegyszerűbb kódot, és a legrosszabb magasság legközelebbi logn. Egy fa 1000000 elemek, egy AVL lesz a legtöbb magasságú 29, egy RB 40, és egy súlyt egyensúlyban 36 vagy 50 attól függően, hogy az arány.
Van egy csomó más változók: véletlenszerű, aránya hozzáadása, törlése, keresések, stb
Ez tényleg a használattól függ. AVL-fa általában több forgatások kiegyensúlyozás. Tehát, ha az alkalmazás nem túl sok behelyezését és a törlést, de súlyok erősen keresést, akkor AVL fa valószínűleg egy jó választás.
std::map használja Piros-fekete fa, mint kap egy ésszerű kompromisszum a sebesség csomópont beszúrás / törlés és keresés.
Frissítse 2017/06/14: webbertiger szerkesztéséhez válasz után azt nyilatkozta. Emlékeztetnék arra, hogy a válasz már sokkal jobb a szemembe. De én csak a válasz, ahogy további információt ...
Tekintettel arra, hogy azt hiszem, az első válasz rossz (korrekció: nem mind többé), a harmadik pedig egy rossz megerősítés. Úgy érzem, meg kellett tisztázni a dolgokat ...
A 2 legnépszerűbb fánk, AVL és piros fekete (RB). A fő különbség rejlik a hasznosítás:
A fő különbség származik a színező. Ugye kevesebb újra egyensúly fellépés RB fa mint AVL, mert a színező lehetővé teszi, hogy néha kihagyja vagy lerövidítheti újra egyensúlyt intézkedéseket, amelyek relatív hi költség. Mivel a színezés, RB fa is magasabb szintű csomópont, mert tudta fogadni piros pontokat a fekete is (amelynek lehetőségeit ~ 2x több szinten), hogy a keresés (read) egy kicsit kevésbé hatékony ... de mivel ez egy állandó (2x), ez marad O (log n).
Ha Ön szerint a teljesítmény találatot módosítását egy fa (kifejező) VS teljesítményét hit konzultáció egy fa (szinte jelentéktelen), akkor természetessé vált, hogy inkább RB felett AVL az általános eset.
A korábbi válaszok kizárólag a fa alternatívák és piros fekete valószínűleg csak marad történelmi okokból.
Miért nem egy hash tábla?
Egy fa típusú igényel csak részleges rendezéssel (<összehasonlítás) kell használni, mint egy kulcs a térképen. Azonban hash táblák előírják, hogy minden kulcs típus egy hash függvény. Hogy ezeket a típusú követelmények minimális nagyon fontos generikus programozás.
Tervezése jó hash tábla igényel mély ismerete a kontextusban, amelyben használni fogják. Amennyiben nyílt címzés, vagy kapcsolt láncolás? Milyen szintű terhelés fogadná átméretezés előtt? Amennyiben használni drága hash, hogy elkerülhető ütközés, vagy az egyik, hogy durva és gyors?
(C ++ 11 tette hozzá hash táblákat unordered_map. Láthatjuk a dokumentációt beállítását követeli politika konfigurálni sok ilyen lehetőség.)
Mivel az STL nem láthatja előre, melyik a legjobb választás a kérelmet, az alapértelmezett kell lennie rugalmasabb. Fák „csak munka” és a skála szépen.
Mi a helyzet más fákat?
Piros Fekete fa ajánlat gyors keresést és önkiegyensúlyozást ellentétben BSTs. Egy másik felhasználó rámutatott a maga előnye a önkiegyensúlyozó AVL fa.
Alexander Stepanov (Az alkotó STL) azt mondta, hogy használja a B-fa helyett piros-fekete fa, ha ő írta std::mapújra. Ez azért van, mert a csomópontok tárolhat egy tetszőleges számú elemet összefüggően, amely barátságosabb a modern memória cache.
Az egyik legnagyobb változás azóta a növekedés cache. Gyorsítótárhibákat nagyon költséges, ezért településen referencia sokkal fontosabb most. Node-alapú adatszerkezetek, amelyek alacsony településen referencia, hogy nem sok értelme van. Ha én tervezése STL ma szerettem volna egy sor különböző konténerek. Például egy memóriában B * -fa egy sokkal jobb választás, mint a piros-fekete fa végrehajtása asszociatív tároló. - Alexander Stepanov
Elolvashatja többet itt
Piros, fekete, fa, vagy B * mindig a legjobb?
Más alkalmakkor Alex kijelentette, hogy std::vectorszinte mindig a legjobb lista tartály hasonló okok miatt. Ritkán van értelme használni std::list, vagy std::dequeakár az olyan helyzetekre, azt tanultuk az iskolában (mint például eltávolítása elemet közepétől a listán). std::vectorolyan gyors, hogy ez veri ezeket a struktúrákat mindent, de nagy n.
Alkalmazása hogy ugyanez az érvelés, ha csak egy kis számú elemet (száz?) Egy std::vectorlineáris keresést hatékonyabb lehet, mint a fa végrehajtását std::map. Attól függően, hogy a gyakorisága beillesztés, a leválogatott std::vectorkombinálva std::binary_searchlehet a leggyorsabb választás.