C # bináris fa és szótárak

szavazat
15

Küzdök a koncepció, ha a bináris keresés fák és mikor kell használni szótárakat.

Az én kérelmet csináltam egy kis kísérlet, amely korábban a C5 könyvtár TreeDictionary(ami szerintem egy piros-fekete bináris keresési fa) és a C # szótárban. A szótár mindig gyorsabb add / megtalálják üzemi és mindig kevesebb memóriát. Például, 16809 <int, float>bejegyzés, a szótár használt 342 KiB míg a fa használt 723 KiB.

Azt hittem, hogy a BST-eket állítólag több memória hatékonyabb, de úgy tűnik, hogy egy csomópont a fa igényel több bájtot egy bejegyzést a szótárban. Mi ad? Van egy pont, ahol a BST-k jobbak, mint a szótárak?

Továbbá, mint egy oldalsó kérdés, nem mindenki tudja, ha van egy gyorsabb + több memóriát igénylő tárolására adatstruktúrát <int, float>párok szótárban típusú hozzáférést, mint akár az említett struktúrák?

A kérdést 28/01/2010 02:46
a forrás felhasználó
Más nyelveken...                            


6 válasz

szavazat
1

Nekem úgy tűnik, te egy korai optimalizálás.

Mi azt javasoljuk, hogy neked, hogy egy interfész izolálni, amelyek szerkezete te tényleg használ, majd végrehajtja az interfész segítségével a szótár (ami úgy tűnik, működik a legjobban).

Ha a memória / teljesítmény lesz probléma (ami valószínűleg nem 20k- számok), akkor létrehozhat más felületet megvalósítások, és ellenőrizze, hogy melyik működik legjobbak. Akkor nem kell változtatni szinte semmit a többi kódot (kivéve végrehajtásának amit használ).

Válaszolt 28/01/2010 03:26
a forrás felhasználó

szavazat
1

Van értelme, hogy egy csomópontja lenne szükség több tároló, mint egy szótár bejegyzés. A bináris fa csomópont szorul érték tárolásához és a bal és jobb oldali részfa. Az általános Dictionary<TKey, TValue>megvalósítása egy hash tábla, amely - felteszem - vagy használja a láncolt lista minden vödör (érték plusz egy pointer / referencia), vagy valamilyen remapping (csak az érték). Azt kell, hogy legyen egy kandikál a reflektor az biztos, de az E kérdés nem hiszem, hogy ez fontos.

A gyérebb a hash tábla, annál kevésbé hatékony a tárolás szempontjából / memória. Ha létrehoz egy hash tábla (szótár) és kezdeti kapacitása 1 millió, és csak töltse meg 10.000 elemeket, akkor biztos vagyok benne, hogy meg fog enni egy csomó több memóriát BST 10.000 csomópontokat.

Mégis, én nem aggódnék sem ezt, ha az összeg a csomópontok / kulcsok csak a több ezer. Ez lesz mérhető a kilobyte, míg GB fizikai RAM.


Ha az a kérdés, hogy „miért akar használni egy bináris fa helyett egy hash tábla?” Akkor a legjobb válasz az, hogy az IMO bináris fák megrendelt mivel hash táblák nem. Csak akkor keresni egy hash tábla a kulcsokat, amelyek pontosan megegyezik valamit; egy fa, akkor keressen egy értéktartomány, a legközelebbi értéket, stb Ez egy nagyon fontos különbség, ha létrehoz egy indexet, vagy valami hasonlót.

Válaszolt 28/01/2010 03:39
a forrás felhasználó

szavazat
0

A felület egy fa és egy hash tábla (ami azt hiszem az, amit a szótár alapja egy) legyen nagyon hasonlóak. Mindig körül forog írtunk kereséseket.

Mindig is hittem a szótár jobb volt létrehozására dolgok egyszer majd ezután pedig sok kereséseket rajta. Bár a fa volt, jobb, ha arra módosításával jelentősen. Azonban nem tudom, hol vettem az ötletet fel.

(Funkcionális nyelvek gyakran fákat, mint az alapját azok darabjai, akkor újra használni a legtöbb fát, ha kicsit módosítani kell azt).

Válaszolt 28/01/2010 03:40
a forrás felhasználó

szavazat
0

Te nem mérjük „almát almával”, a BST kapsz egy megrendelt ábrázolás, amíg egy szótár segítségével csinál egy keresést egy kulcs-érték párt (az Ön esetében).

Én nem sokat várnak méretet a memóriát a 2, de a szótár kapsz egy sokkal gyorsabb keresést. Ahhoz, hogy egy elemet talál a BST akkor (esetleg) van szükség, hogy áthalad az egész fát. De hogy egy dictnary keresési egyszerűen lookup alapján a kulcsot.

Válaszolt 28/01/2010 04:05
a forrás felhasználó

szavazat
8

Azt hittem, hogy a BST-eket állítólag több memória hatékonyabb, de úgy tűnik, hogy egy csomópont a fa igényel több bájtot egy bejegyzést a szótárban. Mi ad? Van egy pont, ahol a BST-k jobbak, mint a szótárak?

Én személyesen soha nem hallottam ilyen elv. Még mindig, az egyetlen általános elve, nem egy kategorikus tény nyomot hagytak a szövet az univerzumban.

Általában szótárak tényleg csak egy díszes borítás körül egy sor kapcsolódó listák. Behelyezi a szótárba, valami ilyesmit:

LinkedList<Tuple<TKey, TValue>> list =
    internalArray[internalArray % key.GetHashCode()];
if (list.Exists(x => x.Key == key))
    throw new Exception("Key already exists");
list.AddLast(Tuple.Create(key, value));

Tehát a közel O (1) működését. A szótár használ O (internalArray.Length + n) memóriát, ahol n tételek száma a gyűjteményben.

Általában BSTs lehet végrehajtani:

  • kapcsolt-listákat, amelyek használata O (n) térben, ahol n az a szám gyűjteményünknek.
  • tömbök , amelyek használata O (2 h - n) térben, ahol h a a fa magasságát és n jelentése az elemek száma a gyűjteményben.
    • Mivel piros-fekete fák egy korlátos magassága O (1,44 * n), egy tömb végrehajtási kell egy korlátos memória használat körülbelül O (2 1.44n - n)

Esélye van, a C5 TreeDictionary alkalmazásával hajtják végre tömbök, ami valószínűleg felelős elvesztegetett hely.

Mi ad? Van egy pont, ahol a BST-k jobbak, mint a szótárak?

Szótár néhány nemkívánatos tulajdonságok:

  • Lehet, hogy nincs elég continugous memóriablokkokkal, hogy tartsa a szótárba, akkor is, ha a memória igénye jóval kisebb, mint a teljes RAM-ot.

  • Értékeli a hash függvény vehet egy tetszőlegesen hosszú ideig. Strings, például a használat Reflektor, hogy megvizsgálja a System.String.GetHashCodemódszer - akkor észre tördeljük string mindig O (n) idő alatt, ami azt jelenti, hogy jelentős időt igényel a nagyon hosszú szálakat. A kéz, összehasonlítva húrok egyenlőtlenség szinte mindig gyorsabb, mint tördeljük, mert szükség lehet nézi csak az első néhány karakter. A teljes egészében lehetővé fa betétek gyorsabb, mint a szótárban betétekkel ha hash kód értékelési túl sokáig tart.

    • Int32 a GetHashCodemódszer szó szerint csak return this, így azt kell zaklatott, hogy megtalálja az esetben, ha a hash és int kulcsok lassabb, mint egy fa szótárban.

RB Fák néhány előnyös tulajdonságokkal rendelkeznek:

  • Megtalálható / eltávolítani a Min és Max elemek O (log n) idő alatt, míg az O (n) idő alatt egy szótár.

  • Ha egy fa van megvalósítva láncolt lista helyett egy tömböt, a fa általában több helyet hatékonyabb, mint egy szótár.

  • Hasonlóképpen, a nevetséges könnyű írni megváltoztathatatlan változatai fák, amelyek támogatják betét / keresési / törlése O (log n) időben. Szótár nem jól alkalmazkodnak a állandóság, hiszen meg kell másolni az egész tömb belső minden művelet (igazából már látott néhány tömb alapú megvalósítások megváltoztathatatlan ujj fák, egyfajta általános célú szótár adatszerkezet, de a megvalósítás nagyon összetett).

  • Tudod áthaladva minden elemét egy fa rendezett sorrendben állandó térben és O (n) idő alatt, míg meg kéne dobni egy hash tábla egy tömb, és rendezni, hogy ugyanazt a hatást.

Szóval, a választás az adatok szerkezete valójában attól függ, milyen tulajdonságokat van szüksége. Ha csak azt, rendezetlen táska és garantálja, hogy a hash függvény értékeli gyorsan megy a Net szótár. Ha szüksége van egy rendezett táskát, vagy egy lassú futás hash függvény, menjen TreeDictionary.

Válaszolt 28/01/2010 04:16
a forrás felhasználó

szavazat
0

A egyensúlyban BST előnyös, ha meg kell védeni az adatstruktúra látenciából tüskék és a hash ütközések ellen.

Az előbbi történik, amikor egy tömb hátú szerkezete növekszik egy gets átméretezett, az utóbbi elkerülhetetlen tulajdonsága algoritmus, mint a vetítés végtelen tér korlátozott egész tartományban.

További probléma a .NET, hogy van LOH, és elegendően nagy szótárt befut egy LOH töredezettség. Ebben az esetben használd a BST, a kifizető az ár nagyobb algoritmikus komplexitás osztályban.

Röviden, a BST mögött a kiosztási kupac kap legrosszabb esetben O (log (n)) időben, hash kapsz O (N) legrosszabb esetben időben.

BST ára O (log (n)) átlagos idő, rosszabb cache településen és több kupac juttatások, de van lappangási garanciákat és védve van a szótár alapú támadások és a memória töredezettség.

Érdemes megjegyezni, hogy a BST is figyelemmel memória töredezettség más platformokon, nem használ tömörítő szemétgyűjtő.

Ami a memória méretét, a .NET Dictionary`2 osztály több memóriát hatékony, mert tárolja az adatokat, mint egy off-halom láncolt lista, amely csak tárolja érték és az eltolás információt. BST kell tárolnia tárgy header (mint minden csomópont egy osztály például a kupac), két pointert, és néhány kiegészített fa adatokat kiegyensúlyozott fák. Például egy piros-fekete fa kellene egy logikai értelmezni, színes (piros vagy fekete). Ez legalább 6 gép szóval, ha nem tévedek. Tehát, minden csomópont egy piros-fekete fa 64 bites rendszerben minimum:

3 szó a header = 24 bájt 2 szót a gyermek mutató = 16 bájt 1 szót a color = 8 bájt legalább 1 szó értéke 8+ bájt = 16 + 24 + 8 + 8 = 56 bájt (8 bájt ha a fa használ szülőcsomópontot pointer).

Ugyanakkor, a legkisebb méret a szócikk lenne csak 16 bájt.

Válaszolt 10/12/2018 13:18
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more