Sling (lano, šňůra) je datová struktura, která umožňuje efektivně ukládat a zpracovávat dlouhé řetězce, například text. Poskytuje uložení dlouhého řetězce jako stromu sestávajícího z malých podřetězců. Je vhodný pro ukládání a zpracování textových souborů a poskytuje efektivní provádění operací typických pro textový editor: vkládání, mazání, obrácení (náhodný přístup) [1] .
Závěs je binární strom, kde každý list (uzel bez potomků) obsahuje řetězec (podřetězec textu) a délku (váhu) a každý nelistový uzel stromu obsahuje délku listů svého levého potomka podstromu. . Uzel se dvěma dětmi rozdělí celý řetězec na dvě části, kde první část je uložena u levého podstromu, druhá - u pravého, váha samotného uzlu je rovna délce první části. Pro základní operace se předpokládá, že řetězce nejsou upravovány nedestruktivním způsobem, což umožňuje kopírování při zápisu. Listové uzly jsou obvykle implementovány jako řetězce konstantní délky s referenčním počtem, při resetování se uvolní paměť. Lze také použít pokročilé techniky sběru odpadu.
V následujících definicích je N délka závěsu.
Tuto operaci lze provést pomocí Split()a dvou operací Concat().
Abychom se podívali na i -tý znak, zahájíme rekurzivní vyhledávání počínaje kořenem:
index funkce ( uzel RopeNode , celé číslo i ) if node . váha <= i a existuje ( node . right ) pak návrat index ( node . right , i - node . weight ) end if existuje ( node . left ) then return index ( node . left , i ) end návratový uzel . řetězec [ i ] konecPodívejte se například na obrázek 2.1 a najděte znak na pozici i=10, začínáme od kořene (A), máme, že jeho váha 22 je větší než 10, takže jdeme dolů doleva (B). Zde máme, že 9 je menší než 10, odečtěte 9 od 10 (získání i=1) a přejděte ke správnému podřízenému uzlu (D). Máme 6 větších než 1 a přejdeme k levému dítěti (G). Zde 2 je větší než 1 jdeme dolů doleva (J). A konečně, 2 je větší než 1, ale protože se jedná o listový uzel, nemá žádné potomky a my se jednoduše odkážeme na index 1 uložený v uzlu řetězce "na" (tedy "a"), který být odpovědí.
Řetězení se provádí vytvořením nového kořene s dětmi vlevo = S1 a vpravo = S2 , v konstantním čase. Váha nadřazeného uzlu je nastavena na délku levého potomka S 1 , který může mít O(log N) , pokud je strom vyvážený.
Většina vázacích operací vyžaduje, aby byl strom vyvážen, po zavěšení může být nutné strom vyvážit.
Jsou možné dva případy:
Druhý případ je zredukován na první tak, že se řetězec přeruší v bodě přerušení a vytvoří se dva nové koncové uzly a poté se pro ně vytvoří nový nadřazený uzel.
Chcete-li například rozdělit smyčku o 22 znacích na obrázku 2.3 na dvě složky o délce 11, požádáme o 12. znak pro určení uzlu K na spodní úrovni. Odstraňte spojení mezi K a G . Přejděte na rodič G a odečtěte váhu K od hmotnosti D . Vylezte po stromu nahoru a odstraňte všechny pravé odkazy podstromu obsahující znaky za 11. znakem odečtením váhy K od jejich nadřazených uzlů (v našem případě pouze D a A ). Nakonec seřadíme nedávno osiřelé uzly K a H tak, že pro ně vytvoříme nového rodiče P s váhou rovnou délce levého dceřiného uzlu K .
Většina operací vázání vyžaduje, aby byl strom vyvážen, po vytyčení může být nutné strom vyvážit.
Dá se to udělat dvěma Split()a jedním Concat(). Pro začátek vydělíme řetězec třemi, oddělenými i -tým a i + j -tým znakem, řádek, který se má smazat, bude přidělen samostatnému (střednímu) uzlu. Poté propojíme další dva uzly.
Chcete-li se dotázat na řetězec C i , …, C i + j − 1 , najděte uzel u obsahující C i c a poté navštivte T počínaje uzlem u . Odvozujeme C i , …, C i + j − 1 navštěvující T v pořadí počínaje uzlem u . weight(u) >= j
Úkon | Sling | pole |
---|---|---|
odvolání [1] | O(log n) | O(1) |
Rozdělení [1] | O(log n) | O(1) |
Zapřáhnout (zničit) | O(log n) nevyvážený / O(n) nejhorší případ | Na) |
Spojka (nedestruktivní) | Na) | Na) |
Průchod postavy [1] | Na) | Na) |
Vložit [2] | O(log n) nevyvážený / O(n) nejhorší případ | Na) |
Dodatek [2] | O(log n) nevyvážený / O(n) nejhorší případ | O(1) odpružené, O(n) nevyvážené |
Odstranění | O(log n) | Na) |
Žádost | O(j + log n) | O(j) |
Stvoření | Na) | Na) |
výhody:
nedostatky:
Tato tabulka porovnává algoritmické vlastnosti implementací řetězců a závěsů, nikoli jejich hrubou rychlost . Řetězce na polích jsou méně režijní, takže například zřetězení a dělení bude pro malé řetězce mnohem rychlejší. Při použití polí pro dlouhé řetězce však již bude časová složitost a náklady na paměť nepřijatelně velké (protože počet kopií se značně zvýší). Naproti tomu výkon je nezávislý na délce dat. Kromě toho se paměťová složitost v obou reprezentacích odhaduje na O(n). Abych to shrnul, smyčky jsou preferovány, když jsou šňůry velmi dlouhé a často se mění.
Struny | |
---|---|
Míry podobnosti řetězců | |
Hledání podřetězců | |
palindromy | |
Sekvenční zarovnání | |
Struktury přípon | |
jiný |