Datové struktury a algoritmy

Výukový program pro datovou strukturu tabulky hash

Výukový program pro datovou strukturu tabulky hash
Ve výpočetní technice znamená slovo „mapa“ propojení položky v jedné sadě s jinou položkou v jiné sadě. Představte si, že na stránce jsou vlevo slova v kruhu a na pravé straně stejné stránky je další kruh, ve kterém jsou další slova. Předpokládejme, že v každém kruhu jsou slova napsána náhodně a jsou rozptýlena v kruhu. Předpokládejme také, že slova v levém kruhu se nazývají klíče a slova v pravém kruhu se nazývají hodnoty. Pokud je šipka nakreslena z každého slova nalevo do každého slova napravo, pak by se řeklo, že klíče byly namapovány na hodnoty.

Předpokládejme, že jste vlastníkem velkého obchodu s potravinami v kraji, kde žijete. Předpokládejme, že žijete ve velké oblasti, která není komerční oblastí. Nejste jediný, kdo má v této oblasti obchod s potravinami; máte několik konkurentů. A pak vás napadne, že byste měli zaznamenat telefonní čísla vašich zákazníků do sešitu. Cvičebnice je samozřejmě malá a nemůžete zaznamenat všechna telefonní čísla všech vašich zákazníků.

Rozhodnete se tedy zaznamenat pouze telefonní čísla vašich stálých zákazníků. A tak máte stůl se dvěma sloupci. Sloupec vlevo obsahuje jména zákazníků a sloupec vpravo obsahuje odpovídající telefonní čísla. Tímto způsobem existuje mapování mezi jmény zákazníků a telefonními čísly. Pravý sloupec tabulky lze považovat za základní hashovací tabulku. Jména zákazníků se nyní nazývají klíče a telefonní čísla se nazývají hodnoty. Pamatujte, že když zákazník přejde na převod, budete muset zrušit jeho řádek a nechat řádek prázdný nebo být nahrazen řádkem nového běžného zákazníka. Všimněte si také, že postupem času se počet stálých zákazníků může zvyšovat nebo snižovat, a tak se tabulka může zvětšovat nebo zmenšovat.

Jako další příklad mapování předpokládejme, že v kraji existuje klub zemědělců. Ne všichni farmáři samozřejmě budou členy klubu. Někteří členové klubu nebudou řádnými členy (účast a příspěvek). Barman se může rozhodnout zaznamenat jména členů a jejich výběr nápoje. Vyvinul tabulku dvou sloupců. Do levého sloupce zapíše jména členů klubu. Do pravého sloupce zapíše odpovídající výběr nápoje.

Zde nastal problém: v pravém sloupci jsou duplikáty. To znamená, že stejný název nápoje se nachází více než jednou. Jinými slovy, různí členové pijí stejný sladký nápoj nebo stejný alkoholický nápoj, zatímco ostatní členové pijí jiný sladký nebo alkoholický nápoj. Bar-man se rozhodne tento problém vyřešit vložením úzkého sloupce mezi dva sloupce. V tomto prostředním sloupci, počínaje shora, čísluje řádky začínající od nuly (tj.E. 0, 1, 2, 3, 4 atd.), dolů, jeden index na řádek. Tím je jeho problém vyřešen, protože jméno člena se nyní mapuje na index, a ne na název nápoje. Jelikož je nápoj identifikován indexem, je jméno zákazníka mapováno na odpovídající index.

Samotný sloupec hodnot (nápoje) tvoří základní hashovací tabulku. V upravené tabulce tvoří sloupec indexů a jejich přidružené hodnoty (s duplikáty nebo bez nich) normální hashovací tabulku - úplná definice hash tabulky je uvedena níže. Klíče (první sloupec) nemusí nutně tvořit součást hash tabulky.

Jako další příklad zvažte opět síťový server, kde může uživatel ze svého klientského počítače přidat nějaké informace, odstranit některé informace nebo upravit některé informace. Existuje mnoho uživatelů serveru.  Každé uživatelské jméno odpovídá heslu uloženému na serveru. Ti, kteří udržují server, mohou vidět uživatelská jména a odpovídající heslo, a tak mohou poškodit práci uživatelů.

Vlastník serveru se tedy rozhodne vytvořit funkci, která zašifruje heslo před jeho uložením. Uživatel se přihlásí na server pomocí svého běžného srozumitelného hesla. Nyní je však každé heslo uloženo v zašifrované podobě. Pokud někdo uvidí zašifrované heslo a pokusí se pomocí něj přihlásit, nebude to fungovat, protože přihlašování obdrží server srozumitelným heslem, nikoli zašifrované heslo.

V tomto případě je klíčem srozumitelné heslo a hodnotou je šifrované heslo. Pokud je šifrované heslo ve sloupci šifrovaných hesel, pak je tento sloupec základní hash tabulkou. Pokud tomuto sloupci předchází další sloupec s indexy začínajícími od nuly, takže každé šifrované heslo je spojeno s indexem, pak sloupec indexů i sloupec šifrovaného hesla tvoří normální hashovací tabulku. Klíče nemusí být nutně součástí hash tabulky.

V tomto případě si všimněte, že každý klíč, kterým je srozumitelné heslo, odpovídá jménu uživatele. Existuje tedy uživatelské jméno, které odpovídá klíči, který je namapován na index, který je přidružen k hodnotě, která je zašifrovaným klíčem.

Níže je uvedena definice hashovací funkce, úplná definice hashovací tabulky, význam pole a další podrobnosti. Abyste mohli ocenit zbytek tohoto tutoriálu, musíte mít znalosti o ukazatelích (odkazech) a propojených seznamech.

Význam hashovací funkce a hashovací tabulky

Pole

Pole je sada po sobě jdoucích paměťových míst. Všechna místa jsou stejné velikosti. K hodnotě v prvním umístění se přistupuje pomocí indexu 0; hodnota v druhém umístění je přístupná s indexem, 1; třetí hodnota je přístupná s indexem, 2; čtvrtý s indexem, 3; a tak dále. Pole se obvykle nemůže zvětšit ani zmenšit. Aby bylo možné změnit velikost (délku) pole, je třeba vytvořit nové pole a do nového pole zkopírovat odpovídající hodnoty. Hodnoty pole jsou vždy stejného typu.

Funkce hash

V softwaru je funkce hash funkce, která převezme klíč a vytvoří odpovídající index pro buňku pole. Pole má pevnou velikost (pevnou délku). Počet klíčů má libovolnou velikost, obvykle větší než velikost pole. Index vyplývající z funkce hash se nazývá hodnota hash nebo digest nebo kód hash nebo jednoduše hash.

Tabulka hash

Hašovací tabulka je pole s hodnotami, na jehož indexy jsou mapovány klíče. Klíče jsou nepřímo mapovány na hodnoty. Ve skutečnosti se říká, že klíče jsou mapovány na hodnoty, protože každý index je spojen s hodnotou (s duplikáty nebo bez nich). Funkce, která mapuje (tj.E. hashing) vztahuje klíče k indexům pole a ne skutečně k hodnotám, protože v hodnotách mohou být duplikáty. Následující diagram ilustruje tabulku hash pro jména lidí a jejich telefonní čísla. Buňky pole (sloty) se nazývají kbelíky.

Všimněte si, že některé segmenty jsou prázdné. Tabulka hash nesmí nutně obsahovat hodnoty ve všech jejích kbelích. Hodnoty v segmentech nemusí být nutně ve vzestupném pořadí. Indexy, ke kterým jsou přidruženy, jsou však vzestupně. Šipky označují mapování. Všimněte si, že klíče nejsou v poli. Nemusí být v žádné struktuře. Funkce hash přebírá jakýkoli klíč a hashuje index pro pole. Pokud v sektoru není žádná hodnota spojená s hašováním indexu, může být do tohoto segmentu vložena nová hodnota. Logický vztah je mezi klíčem a indexem, nikoli mezi klíčem a hodnotou přidruženou k indexu.

Hodnoty pole, stejně jako hodnoty této hash tabulky, jsou vždy stejného datového typu. Hašovací tabulka (kbelíky) může připojit klíče k hodnotám různých datových typů. V tomto případě jsou hodnoty pole všechny ukazatele ukazující na různé typy hodnot.

Hašovací tabulka je pole s hashovací funkcí. Funkce vezme klíč a hashuje odpovídající index, a tak připojí klíče k hodnotám v poli. Klíče nemusí být součástí hash tabulky.

Proč Array a není propojený seznam pro Hash Table

Pole pro hashovací tabulku lze nahradit datovou strukturou propojeného seznamu, ale došlo by k problému. První prvek propojeného seznamu je přirozeně na indexu 0; druhý prvek je přirozeně na indexu, 1; třetí je přirozeně na indexu, 2; a tak dále. Problém s propojeným seznamem spočívá v tom, že k načtení hodnoty musí být seznam iterován, což zabere nějaký čas. Přístup k hodnotě v poli je náhodný přístup. Jakmile je index znám, hodnota se získá bez iterace; tento přístup je rychlejší.

Kolize

Funkce hash přebírá klíč a hashuje odpovídající index, čte přidruženou hodnotu nebo vloží novou hodnotu. Pokud je účelem číst hodnotu, zatím neexistuje žádný problém (žádný problém). Pokud je však účelem vložit hodnotu, může mít hašovaný index již přidruženou hodnotu, a to je kolize; novou hodnotu nelze dát tam, kde již existuje. Existují způsoby, jak vyřešit kolizi - viz níže.

Proč dochází ke kolizi

Ve výše uvedeném příkladu obchodu s obchody jsou klíče názvy zákazníků a názvy nápojů jsou hodnoty. Všimněte si, že zákazníků je příliš mnoho, zatímco pole má omezenou velikost a nemůže přijmout všechny zákazníky. V poli jsou tedy uloženy pouze nápoje běžných zákazníků. Ke kolizi dojde, když se stane nepravidelný zákazník pravidelným. Zákazníci obchodu tvoří velkou sadu, zatímco počet segmentů pro zákazníky v poli je omezený.

U hash tabulek jsou zaznamenány hodnoty pro klíče, které jsou velmi pravděpodobné. Když se klíč, který nebyl pravděpodobný, stane pravděpodobným, pravděpodobně by došlo ke kolizi. Ve skutečnosti ke kolizi vždy dochází u hash tabulek.

Základy řešení kolizí

Dva přístupy k řešení kolizí se nazývají oddělené řetězení a otevřené adresování. Teoreticky by klíče neměly být v datové struktuře nebo by neměly být součástí hash tabulky. Oba přístupy však vyžadují, aby klíčový sloupec předcházel hašovací tabulku a stal se součástí celkové struktury. Místo toho, aby byly klíče ve sloupci klíčů, mohou být ukazatele na klíče ve sloupci klíčů.

Praktická hash tabulka obsahuje sloupec klíčů, ale tento sloupec klíčů není oficiálně součástí hash tabulky.

Buď přístup k rozlišení může mít prázdné kbelíky, ne nutně na konci pole.

Samostatné řetězení

V samostatném řetězení, když dojde ke kolizi, je nová hodnota přidána napravo (ne nad nebo pod) od srazené hodnoty. Takže dvě nebo tři hodnoty mají stejný index. Zřídka by více než tři měly mít stejný index.

Může mít více než jedna hodnota skutečně stejný index v poli? - Ne. V mnoha případech je tedy první hodnota indexu ukazatel na datovou strukturu propojeného seznamu, která obsahuje jednu, dvě nebo tři hodnoty srazené. Následující diagram je příkladem hashovací tabulky pro samostatné zřetězení zákazníků a jejich telefonních čísel:

Prázdné kbelíky jsou označeny písmenem x. Zbytek slotů má odkazy na propojené seznamy. Každý prvek propojeného seznamu má dvě datová pole: jedno pro jméno zákazníka a druhé pro telefonní číslo. Konflikt nastává u klíčů: Peter Jones a Suzan Lee. Odpovídající hodnoty se skládají ze dvou prvků jednoho propojeného seznamu.

U konfliktních klíčů je kritériem pro vložení hodnoty stejné kritérium, které se používá k vyhledání (a čtení) hodnoty.

Otevřete adresování

Při otevřeném adresování jsou všechny hodnoty uloženy v poli kbelíku. Dojde-li ke konfliktu, nová hodnota se vloží do prázdného segmentu nového odpovídající hodnoty konfliktu, a to podle určitých kritérií. Kritérium použité k vložení hodnoty při konfliktu je stejné kritérium použité k vyhledání (hledání a čtení) hodnoty.

Následující diagram ilustruje řešení konfliktů s otevřeným adresováním:

Funkce hash převezme klíč, Peter Jones a hašuje index, 152, a uloží své telefonní číslo do příslušného segmentu. Po nějaké době má hashovací funkce stejný index, 152 od klíče, Suzan Lee, kolidující s indexem pro Petera Jonese. Abychom to vyřešili, hodnota pro Suzan Lee je uložena v kbelíku dalšího indexu 153, který byl prázdný. Funkce hash hashuje index, 153 pro klíč, Robin Hood, ale tento index již byl použit k vyřešení konfliktu pro předchozí klíč. Takže hodnota pro Robina Hooda je umístěna do dalšího prázdného kbelíku, což je hodnota indexu 154.

Metody řešení konfliktů pro samostatné řetězení a otevřené adresování

Samostatné řetězení má své metody řešení konfliktů a otevřené řešení má také své vlastní metody řešení konfliktů.

Metody řešení konfliktů oddělených řetězců

Nyní jsou stručně vysvětleny metody pro oddělené tabulky hash řetězení:

Samostatné řetězení s propojenými seznamy

Tato metoda je vysvětlena výše. Každý prvek propojeného seznamu však nemusí nutně mít klíčové pole (např.G. výše uvedené pole se jménem zákazníka).

Samostatné řetězení s hlavičkovými buňkami seznamu

V této metodě je první prvek propojeného seznamu uložen v kbelíku pole. To je možné, pokud je datový typ pro pole prvkem propojeného seznamu.

Samostatné řetězení s jinými strukturami

Místo propojeného seznamu lze použít jakoukoli jinou datovou strukturu, jako je Self-Balancing Binary Search Tree, který podporuje požadované operace, viz dále.

Metody řešení otevřených konfliktů adresování

Metoda řešení konfliktu v otevřeném adresování se nazývá posloupnost sondy. Nyní jsou stručně vysvětleny tři známé sekvence sondy:

Lineární sondování

Při lineárním sondování se při konfliktu hledá nejbližší prázdný kbelík pod kbelíkem při konfliktu. S lineárním sondováním jsou klíč i jeho hodnota uloženy ve stejném segmentu.

Kvadratické sondování

Předpokládejme, že ke konfliktu dojde na indexu H. Další prázdný slot (kbelík) v indexu H + 12 se používá; pokud je již obsazený, pak další prázdný v H + 22 je použito, pokud je již obsazeno, pak další prázdné v H + 32 se používá atd. K tomu existují varianty.

Double Hashing

S dvojitým hashováním existují dvě hashovací funkce. První počítá (hashuje) index. Pokud dojde ke konfliktu, druhý použije stejný klíč k určení, jak daleko by měla být hodnota vložena. Je toho více - viz dále.

Funkce Perfect Hash

Perfektní hashovací funkce je hashovací funkce, která nemůže vést ke kolizi. To se může stát, když je sada klíčů relativně malá a každý klíč se mapuje na konkrétní celé číslo v hash tabulce.

V sadě znaků ASCII lze velká písmena mapovat na odpovídající malá písmena pomocí hash funkce. Písmena jsou v paměti počítače reprezentována jako čísla. V znakové sadě ASCII je A 65, B 66, C 67 atd. a a je 97, b je 98, c je 99 atd. Chcete-li mapovat z bodu A do bodu a, přidejte 32 až 65; k mapování z B do b přidejte 32 až 66; k mapování z C do c přidejte 32 až 67; a tak dále. Zde jsou velká písmena klávesy a malá písmena jsou hodnoty. Tabulka hash pro toto může být pole, jehož hodnoty jsou přidružené indexy. Pamatujte, že kbelíky pole mohou být prázdné. Takže kbelíky v poli od 64 do 0 mohou být prázdné. Funkce hash jednoduše přidá 32 k číslu kódu velkých písmen, aby získala index, a tedy malé písmeno. Taková funkce je perfektní hashovací funkcí.

Hašování z celočíselných na celočíselné indexy

Existují různé metody hašování celého čísla. Jeden z nich se nazývá Modulo Division Method (Function).

Funkce hash modulové divize

Funkce v počítačovém softwaru není matematická funkce. Ve výpočetní technice (software) se funkce skládá ze sady příkazů, před nimiž jsou argumenty. Pro funkci Modulo Division jsou klíče celá čísla a jsou mapována na indexy pole kbelíků. Sada klíčů je velká, takže by byly mapovány pouze klíče, u kterých je velmi pravděpodobné, že se vyskytnou v aktivitě. Ke kolizím tedy dochází, když je třeba mapovat nepravděpodobné klíče.

V prohlášení,

20/6 = 3R2

20 je dividenda, 6 je dělitel a 3 zbytek 2 je kvocient. Zbytek 2 se také nazývá modulo. Poznámka: je možné mít modulo 0.

Pro toto zatřiďování je velikost tabulky obvykle síla 2, např.G. 64 = 26 nebo 256 = 28, atd.  Dělitelem této hashovací funkce je prvočíslo blízké velikosti pole. Tato funkce vydělí klíč dělitelem a vrátí modulo. Modulo je index pole kbelíků. Přidružená hodnota v kbelíku je hodnota podle vašeho výběru (hodnota klíče).

Klávesy s proměnnou délkou

Zde jsou klíče sady klíčů texty různých délek. Do paměti lze uložit různá celá čísla se stejným počtem bajtů (velikost anglického znaku je bajt). Pokud mají různé klíče různé velikosti bajtů, říká se o nich, že mají proměnnou délku. Jedna z metod hašování proměnných délek se nazývá Radix Conversion Hashing.

Radix konverze hash

V řetězci je každý znak v počítači číslo. V této metodě,

Hash kód (index) = x0Ak − 1+X1Ak − 2+… + Xk − 2A1+Xk − 1A0

Kde (x0, x1,…, xk − 1) jsou znaky vstupního řetězce a a je radix, e.G. 29 (viz dále). k je počet znaků v řetězci. Je toho více - viz dále.

Klíče a hodnoty

V páru klíč / hodnota nemusí být nutně hodnota číslo nebo text. Může to být také záznam. Záznam je seznam napsaný vodorovně. V páru klíč / hodnota může každý klíč ve skutečnosti odkazovat na nějaký jiný text nebo číslo nebo záznam.

Asociativní pole

Seznam je datová struktura, kde položky seznamu souvisejí, a v seznamu existuje sada operací. Každá položka seznamu se může skládat z dvojice položek. Obecnou hashovací tabulku s jejími klíči lze považovat za datovou strukturu, ale jde spíše o systém než o datovou strukturu. Klíče a jejich odpovídající hodnoty nejsou navzájem příliš závislé. Nemají spolu moc společného.

Na druhou stranu je asociativní pole podobná věc, ale klíče a jejich hodnoty jsou na sobě velmi závislé; jsou navzájem velmi příbuzní. Například můžete mít asociativní řadu ovoce a jejich barev. Každé ovoce má přirozeně svou barvu. Klíčem je název ovoce; barva je hodnota. Během vkládání je každý klíč vložen se svou hodnotou. Při mazání je každý klíč odstraněn s jeho hodnotou.

Asociativní pole je datová struktura tabulky hash složená z párů klíč / hodnota, kde pro klíče neexistuje duplikát. Hodnoty mohou mít duplikáty. V této situaci jsou klíče součástí struktury. To znamená, že klíče musí být uloženy, zatímco u běžné tabulky hast nemusí být klíče uloženy. Problém duplikovaných hodnot je přirozeně vyřešen indexy řady segmentů. Nezaměňujte mezi duplikovanými hodnotami a kolizí v indexu.

Protože asociativní pole je datová struktura, má alespoň následující operace:

Asociativní operace s poli

vložit nebo přidat

Tím se do kolekce vloží nový pár klíč / hodnota mapující klíč na jeho hodnotu.

znovu přiřadit

Tato operace nahradí hodnotu konkrétního klíče novou hodnotou.

odstranit nebo odstranit

Tím se odstraní klíč plus jeho odpovídající hodnota.

vzhlédnout

Tato operace vyhledá hodnotu konkrétního klíče a vrátí hodnotu (bez jejího odebrání).

Závěr

Datová struktura tabulky hash se skládá z pole a funkce. Tato funkce se nazývá hash funkce. Funkce mapuje klíče na hodnoty v poli prostřednictvím indexů pole. Klíče nemusí být nutně součástí datové struktury. Sada klíčů je obvykle větší než uložené hodnoty. Když dojde ke kolizi, vyřeší se to buď přístupem samostatného zřetězení nebo přístupem otevřeného adresování. Asociativní pole je speciální případ datové struktury hash tabulky.

Hry Jak stáhnout a přehrát Sid Meier's Civilization VI v systému Linux
Jak stáhnout a přehrát Sid Meier's Civilization VI v systému Linux
Úvod do hry Civilization 6 je moderní pojetí klasického konceptu představeného v sérii her Age of Empires. Myšlenka byla docela jednoduchá; začali bys...
Hry Jak nainstalovat a hrát Doom na Linuxu
Jak nainstalovat a hrát Doom na Linuxu
Úvod do Doom Série Doom vznikla v 90. letech po vydání původního Doomu. Byl to okamžitý hit a od té doby herní série získala řadu ocenění a původní Do...
Hry Vulkan pro uživatele Linuxu
Vulkan pro uživatele Linuxu
S každou novou generací grafických karet vidíme, že vývojáři her posouvají hranice grafické věrnosti a přibližují se k fotorealismu. Ale navzdory vešk...