GeeksforGeeks (Čeština)

Stejně jako Merge Sort, i QuickSort je algoritmus Divide and Conquer. Vybírá prvek jako pivot a rozděluje dané pole kolem vybraného pivot. Existuje mnoho různých verzí quickSortu, které vybírají pivot různými způsoby.

  1. Vždy vyberte první prvek jako otočný.
  2. Vždy vyberte poslední prvek jako otočný (implementováno níže)
  3. Vyberte náhodný prvek jako otočný.
  4. Vyberte medián jako pivot.

Klíčovým procesem v quickSortu je partition (). Cíl oddílů je, vzhledem k tomu, že pole a prvek x pole jsou otočné, umístí x na správnou pozici v seřazeném poli a všechny menší prvky (menší než x) umístí před x a všechny větší prvky (větší než x) za X. To vše by mělo být provedeno v lineárním čase.

Pseudokód pro rekurzivní funkci QuickSort:

Algoritmus oddílu | Existuje mnoho způsobů, jak oddíl vytvořit, následující pseudokód využívá metodu uvedenou v knize CLRS. Logika je jednoduchá, vycházíme z levého prvku a sledujeme index menších (nebo rovných) prvků jako i. Pokud při procházení najdeme menší prvek, vyměníme aktuální prvek s arr. Jinak ignorujeme aktuální prvek.

Pseudokód pro partition ()

Ilustrace partition ():

Implementace:
Následující jsou implementace QuickSort:

Výstup:

Sorted array:1 5 7 8 9 10

Analýza QuickSort
Čas potřebný pro QuickSort lze obecně zapsat následovně.

 T(n) = T(k) + T(n-k-1) + (n)

První dva výrazy jsou pro dvě rekurzivní volání, poslední termín pro proces oddílu. k je počet prvků, které jsou menší než pivot.
Čas potřebný pro QuickSort závisí na strategii vstupního pole a oddílu. Následuje tři případy.

Nejhorší případ: Nejhorší případ nastane, když proces oddílu vždy vybere největší nebo nejmenší prvek jako otočný. Pokud vezmeme v úvahu výše strategii rozdělení, kde poslední prvek je vždy vybrán jako pivot, nejhorší případ by nastal, když je pole již tříděno ve vzestupném nebo sestupném pořadí. Následuje nejhorší opakování.

 T(n) = T(0) + T(n-1) + (n)which is equivalent to T(n) = T(n-1) + (n)

Řešení výše uvedeného opakování je (n2).

Nejlepší případ: Nejlepší případ nastane, když proces oddílu vždy vybere střední prvek jako pivot. Následuje opakování pro nejlepší případ.

 T(n) = 2T(n/2) + (n)

Řešení výše uvedeného opakování je (nLogn). Lze to vyřešit pomocí případu 2 Master Theorem.

Průměrný případ:
Abychom provedli analýzu průměrných případů, musíme vzít v úvahu veškerou možnou permutaci pole a vypočítat čas potřebný každou permutací, která není vypadat snadno.
Můžeme získat představu o průměrném případě, když vezmeme v úvahu případ, kdy oddíl umístí prvky O (n / 9) do jedné sady a prvky O (9n / 10) do jiné sady. Následuje opakování pro tento případ.

 T(n) = T(n/9) + T(9n/10) + (n)

Řešení výše uvedeného opakování je také O (nLogn)

Ačkoli nejhorší časová složitost QuickSortu je O (n2), která je více než mnoho jiných třídicích algoritmů jako Merge Sort a Heap Sort, QuickSort je v praxi rychlejší, protože jeho vnitřní smyčka může být efektivně implementována na většině architektur a ve většině reálných dat. QuickSort lze implementovat různými způsoby změnou volby pivot, takže k nejhoršímu případu u daného typu dat dochází zřídka. Sloučení se však obecně považuje za lepší, když jsou data obrovská a uložená v externím úložišti.

Je QuickSort stabilní?
Výchozí implementace není stabilní. Jakýkoli algoritmus řazení však lze stabilizovat tím, že se jako srovnávací parametr použijí indexy.
Je QuickSort na místě?
Podle široké definice algoritmu na místě se kvalifikuje jako algoritmus řazení na místě, protože používá extra prostor pouze pro ukládání rekurzivních volání funkcí, ale ne pro manipulaci se vstupem.

Jak implementovat QuickSort pro propojené seznamy?
QuickSort na Singly Linked List
QuickSort na dvojnásobně propojeném seznamu

Můžeme implementovat QuickSort iterativně?
Ano, přečtěte si Iterativní rychlé řazení.

Proč je pro třídění polí preferováno Quick Sort před MergeSort
Rychlé řazení ve své obecné podobě je místní řazení (tj. nevyžaduje žádné další úložiště), zatímco slučovací řazení vyžaduje O (N) další úložiště, N označuje velikost pole, což může být docela drahé. Přidělením a zrušením přidělení extra prostoru použitého pro sloučení se zvýší doba chodu algoritmu. Porovnáním průměrné složitosti zjistíme, že oba typy mají průměrnou složitost O (NlogN), ale konstanty se liší. U polí dojde ke ztrátě sloučeného řazení v důsledku použití dalšího úložného prostoru O (N).

Nejpraktičtější implementace rychlého řazení používají randomizovanou verzi. Randomizovaná verze má očekávanou časovou složitost O (nLogn).Nejhorší případ je možný také v randomizované verzi, ale nejhorší případ se u konkrétního vzoru nevyskytuje (jako seřazené pole) a randomizované Rychlé řazení funguje v praxi dobře.

Rychlé řazení je také třídění vhodné pro mezipaměť algoritmus, protože má dobrou lokalitu odkazu, když se používá pro pole.

Rychlé řazení je také rekurzivní ocas, proto se provádí optimalizace volání ocasu.

Proč je pro propojené seznamy upřednostňován MergeSort před QuickSort. ?
V případě propojených seznamů se případ liší hlavně kvůli rozdílu v alokaci paměti polí a propojených seznamů. Na rozdíl od polí nemusí propojené uzly seznamu sousedit v paměti. Na rozdíl od pole můžeme v propojeném seznamu vložit položky do středu v O (1) extra prostoru a O (1) času. Operaci sloučení sloučení lze tedy implementovat bez dalšího prostoru pro propojené seznamy.

V polích můžeme provádět náhodný přístup, protože prvky jsou v paměti spojité. Řekněme, že máme celé číslo (4 bajty) pole A a nechme adresu A být x, pak pro přístup k A, můžeme přímo přistupovat k paměti na (x + i * 4). Na rozdíl od polí nemůžeme provést náhodný přístup v propojeném seznamu. Rychlé třídění vyžaduje hodně tohoto druhu přístupu. V propojeném seznamu pro přístup k ith indexu musíme cestovat každým uzlem z hlavy do ith uzlu, protože nemáme nepřetržitý blok paměti. Proto se režie zvyšuje pro rychlé třídění. Sloučit řazení přistupuje k datům postupně a potřeba náhodného přístupu je nízká.

Jak optimalizovat QuickSort tak, aby v nejhorším případě zabralo O (Log n) místo navíc?
Viz Optimalizace QuickSort Tail Call (Zmenšení prostoru pro nejhorší případ na Log n)

Snapshots:

  • Kvíz o QuickSort
  • Poslední články o QuickSort
  • Postup kódování pro třídění.

Další algoritmy řazení na GeeksforGeeks / GeeksQuiz:
Výběr řazení, řazení bublin, třídění podle vložení, sloučení řazení, hromadné řazení, QuickSort , Radix Sort, Count Count Sort, Bucket Sort, ShellSort, Comb Sort, Pigeonhole Sort

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *