Shellsort - Shellsort - Wikipedia
Shellsort s mezerami 23, 10, 4, 1 v akci | |
Třída | Algoritmus řazení |
---|---|
Datová struktura | Pole |
Nejhorší případ výkon | Ó(n2) (nejhorší známá nejhorší sekvence mezery) Ó(n log2n) (nejznámější sekvence mezery v nejhorším případě)[1] |
Nejlepší případ výkon | Ó(n log n) (většina sekvencí mezer) Ó(n log2n) (nejznámější posloupnost nejhorších případů mezery)[2] |
Průměrný výkon | záleží na sekvenci mezer |
Nejhorší případ složitost prostoru | О (n) celkem, O (1) pomocný |
Shellsort, také známý jako Třídění skořápky nebo Shellova metoda, je na místě porovnání řazení. Lze na ni pohlížet jako na zevšeobecnění třídění výměnou (třídění bublin ) nebo třídění vložením (třídění vložení ).[3] Metoda začíná tříděním dvojic prvků daleko od sebe, poté postupně zmenšuje mezeru mezi prvky, které mají být porovnávány. Začíná-li od sebe daleko od sebe, může přesunout některé nepřiměřené prvky do pozice rychleji než jednoduchá výměna nejbližšího souseda. Donald Shell zveřejnil první verzi tohoto druhu v roce 1959.[4][5] Doba běhu Shellsortu silně závisí na sekvenci mezer, kterou používá. U mnoha praktických variant je určování jejich časová složitost zůstává otevřený problém.
Popis
Shellsort je optimalizace třídění vložení který umožňuje výměnu předmětů, které jsou od sebe daleko. Myšlenkou je uspořádat seznam prvků tak, aby počínaje kdekoli a kdekoli htento prvek vytvoří seřazený seznam. Takový seznam se říká h-tříděné. Lze to také považovat za h prokládané seznamy, každý jednotlivě seřazený.[6] Počínaje velkými hodnotami h umožňuje prvkům pohybovat se na dlouhé vzdálenosti v původním seznamu, rychle snižuje velké množství nepořádku a ponechává méně práce menším h-tříděné kroky.[7] Pokud je tedy seznam k-tříděno pro nějaké menší celé číslo k, pak seznam zůstane h-tříděné. V návaznosti na tuto myšlenku pro klesající posloupnost h je zaručeno, že hodnoty končící na 1 nakonec ponechají seřazený seznam.[6]
Zjednodušeně to znamená, že pokud máme pole 1024 čísel, naše první mezera (h) může být 512. Poté projdeme seznamem porovnávajícím každý prvek v první polovině s prvkem ve druhé polovině. Naše druhá mezera (k) je 256, což rozděluje pole na čtyři sekce (počínaje 0,256 512 768) a my se ujistíme, že první položky v každé sekci jsou vzájemně seřazeny, pak druhá položka v každé sekci atd. V praxi může být sekvence mezery cokoli, ale poslední mezera je vždy 1 k dokončení třídění (účinně končící běžným vkládáním).
Níže je uveden příklad běhu Shellsortu s mezerami 5, 3 a 1.
A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Vstupní data | 62 | 83 | 18 | 53 | 07 | 17 | 95 | 86 | 47 | 69 | 25 | 28 |
Po 5-třídění | 17 | 28 | 18 | 47 | 07 | 25 | 83 | 86 | 53 | 69 | 62 | 95 |
Po třídění | 17 | 07 | 18 | 47 | 28 | 25 | 69 | 62 | 53 | 83 | 86 | 95 |
Po 1-třídění | 07 | 17 | 18 | 25 | 28 | 47 | 53 | 62 | 69 | 83 | 86 | 95 |
První průchod, 5-třídění, provádí třídění vložení na pěti samostatných podskupinách (A1, A6, A11), (A2, A7, A12), (A3, A8), (A4, A9), (A5, A10). Například změní podadresář (A1, A6, A11) od (62, 17, 25) do (17, 25, 62). Další průchod, třídění, provede třídění vložení na třech dílčích polích (A1, A4, A7, A10), (A2, A5, A8, A11), (A3, A6, A9, A12). Poslední průchod, 1-třídění, je běžný druh vložení celého pole (A1,..., A12).
Jak ilustruje příklad, subarrays, na kterých pracuje Shellsort, jsou zpočátku krátké; později jsou delší, ale téměř objednané. V obou případech funguje řazení efektivně.
Shellsort není stabilní: může změnit relativní pořadí prvků se stejnými hodnotami. Je to algoritmus adaptivního třídění v tom, že se provádí rychleji, když je vstup částečně tříděn.
Pseudo kód
Pomocí mezerové sekvence Marcina Ciury s vnitřním druhem vložení.
# Seřadit pole a [0 ... n-1].mezery = [701, 301, 132, 57, 23, 10, 4, 1]# Začněte s největší mezerou a snižte se na mezeru 1pro každého (mezera v mezery){ # Udělejte pro tuto velikost mezery třídění vložení s mezerou. # První prvky mezery a [0..gap-1] jsou již v pořadí mezer # přidávejte ještě jeden prvek, dokud nebude celé pole roztříděno podle mezer pro (i = mezera; i < n; i += 1) { # přidat [i] k prvkům, které byly roztříděny podle mezer # uložit [i] do temp a udělat díru na pozici i tepl = A[i] # posunout dřívější prvky seřazené podle mezery nahoru, dokud nenajdete správné umístění pro [i] pro (j = i; j >= mezera a A[j - mezera] > tepl; j -= mezera) { A[j] = A[j - mezera] } # vložte temp (originál a [i]) na správné místo A[j] = tepl }}
Sekvence mezer
Otázka rozhodování, kterou sekvenci mezer použít, je obtížná. Každá sekvence mezery, která obsahuje 1, přináší správné řazení (protože to dělá z posledního průchodu obyčejné řazení); vlastnosti takto získaných verzí Shellsortu však mohou být velmi odlišné. Příliš málo mezer zpomaluje přihrávky a příliš mnoho mezer vytváří režii.
Níže uvedená tabulka porovnává většinu dosud publikovaných navrhovaných sekvencí mezer. Některé z nich mají klesající prvky, které závisí na velikosti seřazeného pole (N). Jiné zvyšují nekonečné sekvence, jejichž prvků je méně než N by měly být použity v opačném pořadí.
OEIS Obecný termín (k ≥ 1) Betonové mezery Nejhorší případ
časová složitostAutor a rok vydání [např. když N = 2str] Shell, 1959[4] Frank & Lazarus, 1960[8] A000225 Hibbard, 1963[9] A083318 , s předponou 1 Papernov a Stasevich, 1965[10] A003586 Postupná čísla formuláře (3-hladký čísla) Pratt, 1971[1] A003462 , ne větší než Knuth, 1973,[3] na základě Pratt, 1971[1] A036569 Incerpi & Sedgewick, 1985,[11] Knuth[3] A036562 , s předponou 1 Sedgewick, 1982[6] A033622 Sedgewick, 1986[12] Neznámý Gonnet & Baeza-Yates, 1991[13] A108870 Neznámý Tokuda, 1992[14] A102549 Neznámé (experimentálně odvozeno) Neznámý Ciura, 2001[15]
Když binární reprezentace N obsahuje mnoho po sobě jdoucích nul, Shellsort s použitím původní sekvence mezer Shell dělá Θ (N2) srovnání v nejhorším případě. Například tento případ nastane pro N rovná se síle dvou, když prvky větší a menší než střední zaujímají liché a sudé pozice, protože jsou porovnávány pouze při posledním průchodu.
Ačkoli to má větší složitost než Ó(N logN), který je optimální pro srovnávací druhy, je vhodná pro Prattovu verzi třídění sítí a má stejnou asymptotickou složitost brány jako Batcher's bitonický třídič.
Gonnet a Baeza-Yates poznamenali, že Shellsort provádí průměrně nejméně srovnání, když jsou poměry po sobě jdoucích mezer zhruba rovné 2,2.[13] Proto se jejich sekvence s poměrem 2,2 a Tokudova sekvence s poměrem 2,25 osvědčily. Není však známo, proč tomu tak je. Sedgewick doporučuje používat mezery, které mají nízké hodnoty největší společní dělitelé nebo jsou párové coprime.[16]
S ohledem na průměrný počet srovnání, Ciurova posloupnost[15] má nejznámější výkon; mezery od 701 nebyly stanoveny, ale sekvenci lze dále prodloužit podle rekurzivního vzorce .
Tokudova sekvence, definovaná jednoduchým vzorcem , kde , , lze doporučit pro praktické aplikace.
Výpočetní složitost
Následující vlastnost platí: po h2-třídění libovolného h1-tříděné pole, pole zůstane h1-tříděné.[17] Každý h1-tříděné a h2-tříděné pole je také (A1h1+A2h2) -tříděné, pro všechna nezáporná celá čísla A1 a A2. Nejhorší případ složitosti Shellsortu je tedy spojen s Frobeniův problém: pro zadaná celá čísla h1,..., hn s gcd = 1, číslo Frobenius G(h1,..., hn) je největší celé číslo, které nelze reprezentovat jako A1h1+ ... +Anhn s nezáporným celým číslem A1,..., An. Pomocí známých vzorců pro čísla Frobenius můžeme určit nejhorší složitost Shellsortu pro několik tříd posloupností mezer.[18] Osvědčené výsledky jsou uvedeny ve výše uvedené tabulce.
Pokud jde o průměrný počet operací, žádný z prokázaných výsledků se netýká praktické sekvence mezer. Pro mezery, které jsou mocninami dvou, vypočítal Espelid tento průměr jako .[19] Knuth určila průměrnou složitost třídění N-prvkové pole se dvěma mezerami (h, 1) být .[3] Z toho vyplývá, že dvouprůchodový Shellsort s h = Θ (N1/3) dělá v průměru Ó(N5/3) srovnání / inverze / doba chodu. Yao zjistil průměrnou složitost třípásmového Shellsortu.[20] Jeho výsledek vylepšili Janson a Knuth:[21] průměrný počet srovnání / inverzí / doby chodu provedených během Shellsortu se třemi mezerami (ch, srov, 1), kde h a G jsou coprime, je při prvním průchodu ve druhém průchodu a ve třetím průchodu. ψ(h, G) v posledním vzorci je složitá funkce asymptoticky rovná . Zejména když h = Θ (N7/15) a G = Θ (N1/5), je průměrná doba třídění Ó(N23/15).
Na základě experimentů se předpokládá, že Shellsort Hibbard běží sekvence mezer Ó(N5/4) průměrný čas,[3] a že sekvence Gonnet a Baeza-Yates vyžaduje průměrně 0,41NlnN(ln lnN+1/6) pohyby prvků.[13] Aproximace průměrného počtu operací dříve předložených pro jiné sekvence selžou, když seřazená pole obsahují miliony prvků.
Níže uvedený graf ukazuje průměrný počet srovnání prvků v různých variantách Shellsortu vydělený teoretickou dolní mezí, tj. Log2N!, kde byla podle vzorce prodloužena sekvence 1, 4, 10, 23, 57, 132, 301, 701 .
Uplatnění teorie Kolmogorovova složitost, Jiang, Li, a Vitányi prokázal následující dolní mez pro pořadí průměrného počtu operací / doby chodu v a str-pass Shellsort: Ω (pN1+1/str) když str≤log2N a Ω (pN) když str> přihlásit2N.[22] Proto má Shellsort vyhlídky na běh v průměrném čase, který asymptoticky roste NlogN pouze při použití sekvencí mezer, jejichž počet mezer roste úměrně k logaritmu velikosti pole. Není však známo, zda Shellsort může dosáhnout tohoto asymptotického řádu průměrné složitosti, což je optimální pro srovnávací druhy. Dolní mez byla vylepšena o Vitányi[23] pro každý počet průchodů na kde . Tento výsledek znamená například dolní hranici Jiang-Li-Vitányi pro všechny -pass přírůstkové sekvence a vylepšuje dolní mez pro konkrétní přírůstkové sekvence. Ve skutečnosti jsou všechny dolní hranice (dolní a horní) aktuálně známé pro průměrný případ přesně shodovány s touto dolní mezí. Například to dává nový výsledek Janson -Knuth horní mez je porovnána s výslednou dolní mezí pro použitou přírůstkovou sekvenci, což ukazuje, že třípásmový Shellsort pro tuto přírůstkovou sekvenci používá srovnání / inverze / doba chodu. Vzorec nám umožňuje hledat přírůstkové sekvence, které dávají dolní hranice, které nejsou známy; například přírůstková sekvence pro čtyři průchody, která má dolní hranici větší než pro přírůstkovou sekvenci. Dolní mez se stává
Nejhorší složitost jakékoli verze Shellsortu je vyššího řádu: Plaxton, Poonen, a Suel ukázal, že roste minimálně stejně rychle jako .[24]
Aplikace
Shellsort provádí více operací a má vyšší poměr chybějících mezipaměti než quicksort. Protože jej však lze implementovat pomocí malého kódu a nepoužívá zásobník volání, některé implementace qsort funkce v C standardní knihovna zaměřeno na vestavěné systémy použijte místo rychlého třídění. Shellsort se například používá v uClibc knihovna.[25] Z podobných důvodů byl v minulosti Shellsort používán v EU Linuxové jádro.[26]
Shellsort může také sloužit jako sub-algoritmus introspektivní řazení, třídit krátké dílčí pole a zabránit zpomalení, když hloubka rekurze překročí daný limit. Tento princip se používá například v bzip2 kompresor.[27]
Viz také
Reference
- ^ A b C Pratt, Vaughan Ronald (1979). Shellsort a třídění sítí (vynikající disertační práce v počítačových vědách). Girlanda. ISBN 978-0-8240-4406-0.
- ^ „Shellsort a srovnání“.
- ^ A b C d E Knuth, Donald E. (1997). "Shellova metoda". Umění počítačového programování. Svazek 3: Třídění a vyhledávání (2. vyd.). Reading, Massachusetts: Addison-Wesley. 83–95. ISBN 978-0-201-89685-5.
- ^ A b Shell, D. L. (1959). „Vysokorychlostní postup třídění“ (PDF). Komunikace ACM. 2 (7): 30–32. doi:10.1145/368370.368387.
- ^ Některé starší učebnice a reference tomu říkají „Shell – Metzner“ Marlene Metzner Norton, ale podle Metznera „neměl jsem s tím druhem nic společného a mé jméno k němu nikdy nemělo být připojeno.“ Vidět "Třídění skořápky". Národní institut pro standardy a technologie. Citováno 17. července 2007.
- ^ A b C Sedgewick, Robert (1998). Algoritmy v jazyce C.. 1 (3. vyd.). Addison-Wesley. str.273–281. ISBN 978-0-201-31452-6.
- ^ Kernighan, Brian W.; Ritchie, Dennis M. (1996). Programovací jazyk C. (2. vyd.). Prentice Hall. p. 62. ISBN 978-7-302-02412-5.
- ^ Frank, R. M .; Lazarus, R. B. (1960). "Vysokorychlostní postup třídění". Komunikace ACM. 3 (1): 20–22. doi:10.1145/366947.366957.
- ^ Hibbard, Thomas N. (1963). "Empirická studie minimálního třídění úložiště". Komunikace ACM. 6 (5): 206–213. doi:10.1145/366552.366557.
- ^ Papernov, A. A .; Stasevich, G. V. (1965). „Metoda třídění informací v počítačových pamětech“ (PDF). Problémy přenosu informací. 1 (3): 63–75.
- ^ Incerpi, Janet; Sedgewick, Robert (1985). "Vylepšené horní hranice na Shellsortu" (PDF). Journal of Computer and System Sciences. 31 (2): 210–224. doi:10.1016 / 0022-0000 (85) 90042-x.
- ^ Sedgewick, Robert (1986). "Nová horní hranice pro Shellsort". Journal of Algorithms. 7 (2): 159–173. doi:10.1016/0196-6774(86)90001-5.
- ^ A b C Gonnet, Gaston H .; Baeza-Yates, Ricardo (1991). „Shellsort“. Příručka algoritmů a datových struktur: In Pascal a C. (2. vyd.). Reading, Massachusetts: Addison-Wesley. 161–163. ISBN 978-0-201-41607-7.
- ^ Tokuda, Naoyuki (1992). "Vylepšený Shellsort". In van Leeuven, Jan (ed.). Sborník z 12. světového počítačového kongresu IFIP o algoritmech, softwaru a architektuře. Amsterdam: North-Holland Publishing Co. str. 449–457. ISBN 978-0-444-89747-3.
- ^ A b Ciura, Marcin (2001). „Nejlepší přírůstky pro průměrný případ Shellsortu“ (PDF). Ve Freiwalds, Rusins (ed.). Sborník z 13. mezinárodního sympozia o základech teorie výpočtu. London: Springer-Verlag. 106–117. ISBN 978-3-540-42487-1.
- ^ Sedgewick, Robert (1998). „Shellsort“. Algoritmy v C ++, části 1–4: Základy, datová struktura, třídění, vyhledávání. Reading, Massachusetts: Addison-Wesley. str. 285–292. ISBN 978-0-201-35088-3.
- ^ Gale, David; Karp, Richard M. (1972). "Fenomén v teorii třídění". Journal of Computer and System Sciences. 6 (2): 103–115. doi:10.1016 / S0022-0000 (72) 80016-3.
- ^ Selmer, Ernst S. (1989). "Na Shellsortu a Frobeniově problému". BIT Numerická matematika. 29 (1): 37–40. doi:10.1007 / BF01932703. hdl:1956/19572.
- ^ Espelid, Terje O. (1973). "Analýza Shellsortova algoritmu". BIT Numerická matematika. 13 (4): 394–400. doi:10.1007 / BF01933401.
- ^ Yao, Andrew Chi-Chih (1980). „Analýza (h, k, 1) -Shellsort ". Journal of Algorithms. 1 (1): 14–50. doi:10.1016/0196-6774(80)90003-6.
- ^ Janson, Svante; Knuth, Donald E. (1997). "Shellsort se třemi přírůstky". Náhodné struktury a algoritmy. 10 (1–2): 125–142. arXiv:cs / 9608105. doi:10.1002 / (SICI) 1098-2418 (199701/03) 10: 1/2 <125 :: AID-RSA6> 3.0.CO; 2-X. CiteSeerX: 10.1.1.54.9911.
- ^ Jiang, Tao; Li, Ming; Vitányi, Paul (2000). „Nižší hranice průměrné složitosti Shellsortu“. Deník ACM. 47 (5): 905–911. arXiv:cs / 9906008. doi:10.1145/355483.355488. CiteSeerX: 10.1.1.6.6508.
- ^ Vitányi, Paul (2018). „O průměrné složitosti Shellsorta“. Náhodné struktury a algoritmy. 52 (2): 354–363. arXiv:cs / 9906008. doi:10.1002 / rsa.20737.
- ^ Plaxton, C. Greg; Poonen, Bjorn; Suel, Torsten (1992). Vylepšené spodní hranice pro Shellsort. Výroční sympozium o základech informatiky. 33. str. 226–235. CiteSeerX 10.1.1.460.2429. doi:10.1109 / SFCS.1992.267769. ISBN 978-0-8186-2900-6. CiteSeerX: 10.1.1.43.1393.
- ^ Novoa, Manuel III. „libc / stdlib / stdlib.c“. Citováno 29. října 2014.
- ^ "kernel / groups.c". Citováno 5. května 2012.
- ^ Julian Seward. „bzip2 / blocksort.c“. Citováno 30. března 2011.
Bibliografie
- Knuth, Donald E. (1997). "Shellova metoda". Umění počítačového programování. Svazek 3: Třídění a vyhledávání (2. vyd.). Reading, Massachusetts: Addison-Wesley. 83–95. ISBN 978-0-201-89685-5.
- Analýza Shellsort a souvisejících algoritmů, Robert Sedgewick, Čtvrté evropské symposium o algoritmech, Barcelona, září 1996.
externí odkazy
- Animované algoritmy řazení: Třídění podle prostředí na Wayback Machine (archivováno 10. března 2015) - grafická ukázka
- Shellsort s mezerami 5, 3, 1 jako maďarský lidový tanec