Heapsort Časová složitost

Heapsort Casova Slozitost



Heap Sort, napsaný jako Heapsort, je druh třídícího algoritmu. Vezme seznam, který je částečně uspořádaný, a vytvoří z něj seřazený seznam. Řazení může být vzestupné nebo sestupné. V tomto článku je řazení vzestupné. Všimněte si, že heapsort nesetřídí neúplně neseřazený seznam. Seřadí částečně uspořádaný (seřazený) seznam. Ten částečně uspořádaný seznam je hromada. V tomto článku je uvažovaná halda minimální (vzestupně) halda.

Hromada se označuje jako „částečně uspořádaná“ a nikoli „částečně roztříděná“. Slovo „sort“ znamená kompletní řazení (kompletní řazení). Hromada není částečně uspořádána libovolně. Halda je částečně uspořádána podle kritéria (vzoru), jak je znázorněno níže.

Heapsort se tedy skládá ze dvou fází: sestavení hromady a extrahování uspořádaného prvku z horní části hromady. Ve druhé fázi se po každé extrakci halda znovu postaví. Každá přestavba je rychlejší než původní stavební proces, protože přestavba se provádí z předchozí stavby, kde byl odstraněn jeden prvek. A s tím heapsort třídí zcela netříděný seznam.







Cílem tohoto článku je stručně vysvětlit heapsort a následně vytvořit jeho časovou složitost (viz význam časové složitosti níže). Ke konci se kódování provádí v C++.



Minimální halda

Halda může být minimální halda nebo maximální halda. Maximální halda je taková, kde první prvek je nejvyšší prvek a celý strom nebo odpovídající seznam je částečně uspořádán v sestupném pořadí. Min-hromada je taková, kde první prvek je nejmenší prvek a celý seznam je částečně seřazen vzestupně. V tomto článku je uvažována pouze minimální hromada. Poznámka: v tématu haldy se prvek nazývá také uzel.



Halda je úplný binární strom. Binární strom může být vyjádřen jako pole (seznam); čtěte shora dolů a zleva doprava. Vlastností haldy pro min-hromadu je, že nadřazený uzel je menší nebo roven každému z jeho dvou potomků. Příkladem neuspořádaného seznamu je:





9 19 24 5 3 jedenáct 14 22 7 6 17 patnáct nula nula nula
0 1 dva 3 4 5 6 7 8 9 10 jedenáct 12 13 14

První řádek této tabulky jsou prvky pole. Ve druhém řádku jsou indexy založené na nule. Tento seznam prvků lze vyjádřit jako strom. Nulové prvky byly přidány, aby se vytvořil úplný binární strom. Přísně vzato, prvky null nejsou součástí seznamu (stromu). Tento seznam nemá pořadí, takže to ještě není hromada. Stane se haldou, když má částečné uspořádání podle vlastnosti haldy.

Vztah mezi uzly a indexy

Pamatujte, že halda je úplný binární strom předtím, než budete mít konfiguraci haldy (vlastnost haldy). Předchozí seznam ještě není halda, protože prvky se neřídí vlastností haldy. Stane se haldou po přeskupení prvků do částečného pořadí podle vlastnosti min-heap. Částečné pořadí může být chápáno jako částečné řazení (ačkoli slovo „sort“ znamená úplné uspořádání).



Ať už je binární strom hromada nebo ne, každý rodič má dvě potomky, kromě listových (posledních) uzlů. Mezi indexy mezi každým rodičem a jeho dětmi existuje matematický vztah. Je to takto: Pokud je rodič na indexu i, pak je levý potomek na indexu:

dva * i + 1

a správné dítě je na indexu:

dva * i + dva

Toto je pro indexování založené na nule. A tak rodič na indexu 0 má svého levého potomka na indexu 2×0+1=1 a jeho pravého potomka na 2×0+2=2. Rodič na indexu 1 má svého levého potomka na indexu 2×1+1=3 a pravého potomka na indexu 2×1+2=4; a tak dále.

Podle vlastnosti min-heap je rodič na i menší nebo roven levému potomkovi v 2i+1 a menší nebo roven pravému potomkovi v 2i+2.

Halda

Hromadit znamená stavět hromadu. Znamená to přeskupit prvky seznamu (nebo odpovídajícího stromu) tak, aby vyhovovaly vlastnosti haldy. Na konci procesu hromadění je seznam nebo strom hromada.

Pokud je předchozí neseřazený seznam nahromaděný, stane se:

3 5 jedenáct 7 6 patnáct 14 22 9 19 17 24 nula nula nula
0 1 dva 3 4 5 6 7 8 9 10 jedenáct 12 13 14

Poznámka: v seznamu je 12 prvků, nikoli 15. Ve druhém řádku jsou indexy. V procesu vytváření haldy bylo nutné prvky zkontrolovat a některé vyměnit.

Všimněte si, že nejmenší a první prvek je 3. Zbytek prvků následuje vzestupně, ale zvlněně. Pokud je levý a pravý potomek na pozicích 2i+1 a 2i+2 větší než nebo stejný jako rodič na i, pak je to min-hromada. Toto není úplné řazení nebo řazení. Toto je částečné řazení podle vlastnosti haldy. Odtud začíná další fáze třídění haldy.

Heapify Time Complexity

Časová složitost je relativní doba běhu nějakého kódu. Může být viděn jako počet hlavních operací, které má tento kód dokončit. Existují různé algoritmy pro vytváření haldy. Nejúčinnější a nejrychlejší průběžně rozdělují seznam po dvou, kontrolují prvky odspodu a poté provádějí nějaké prohození prvků. Nechť N je počet praktických prvků v seznamu. S tímto algoritmem je maximální počet hlavních operací (swapování) N. Časová složitost heapifikace byla dříve dána jako:

Ó ( n )

Kde n je N a je maximální možný počet hlavních operací. Tato notace se nazývá Big-O notace. Začíná velkým písmenem O, za nímž následují závorky. Uvnitř závorek je výraz pro možný nejvyšší počet operací.

Pamatujte: sčítání se může stát násobením, pokud se stále opakuje totéž, co se přidává.

Heapsort ilustrace

Předchozí neseřazený seznam bude použit pro ilustraci heapsortu. Uvedený seznam je:

9 19 24 5 3 jedenáct 14 22 7 6 17 patnáct

Min-hromada vytvořená ze seznamu je:

3 5 jedenáct 7 6 patnáct 14 22 9 19 17 24

První fází v heapsort je vytvoření hromady, která byla vyrobena. Toto je částečně uspořádaný seznam. Nejedná se o seřazený (zcela seřazený) seznam.

Druhá fáze spočívá v odstranění nejmenšího prvku, což je první prvek, z hromady, opětovném nahromadění zbývající hromady a odstranění nejmenšího počtu prvků ve výsledcích. Nejmenší prvek je vždy prvním prvkem v re-heapifyied haldě. Prvky se neodstraňují a nevyhazují. Mohou být odeslány do jiného pole v pořadí, v jakém byly odebrány.

Nakonec by nové pole mělo všechny prvky seřazené (zcela), ve vzestupném pořadí; a už ne jen částečně objednané.

Ve druhé fázi je první věcí, kterou musíte udělat, odstranit 3 a umístit je do nového pole. Výsledky jsou:

3

a

5 jedenáct 7 6 patnáct 14 22 9 19 17 24

Zbývající prvky musí být nahromaděny před extrakcí prvního prvku. Hromada zbývajících prvků se může stát:

5 6 7 9 patnáct 14 22 jedenáct 19 17 24

Extrahováním 5 a přidáním do nového seznamu (pole) získáte výsledky:

3 5

a

6 7 9 patnáct 14 22 jedenáct 19 17 24

Nahromadění zbývající sady by poskytlo:

6 7 9 patnáct 14 22 jedenáct 19 17 24

Extrahováním 6 a přidáním do nového seznamu (pole) získáte výsledky:

3 5 6

a

7 9 patnáct 14 22 jedenáct 19 17 24

Nahromadění zbývající sady by poskytlo:

7 9 jedenáct 14 22 patnáct 19 17 24

Rozbalením 7 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7

a

9 jedenáct 14 22 patnáct 19 17 24

Nahromadění zbývající sady dává:

9 jedenáct 14 22 patnáct 19 17 24

Rozbalením 9 a přidáním do nového seznamu získáte výsledky:

3 5 6 7 9

a

jedenáct 14 22 patnáct 19 17 24

Nahromadění zbývající sady dává:

jedenáct 14 17 patnáct 19 22 24

Rozbalením 11 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct

a

14 17 patnáct 19 22 24

Nahromadění zbývající sady by poskytlo:

14 17 patnáct 19 22 24

Extrahováním 14 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct 14

a

17 patnáct 19 22 24

Nahromadění zbývající sady by poskytlo:

patnáct 17 19 22 24

Extrahováním 15 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct 14 patnáct

a

17 19 22 24

Nahromadění zbývající sady by poskytlo:

17 19 22 24

Extrahováním 17 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct 14 patnáct 17

a

19 22 24

Nahromadění zbývající sady by poskytlo:

19 22 24

Extrahováním 19 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct 14 patnáct 17 19

a

22 24

Nahromadění zbývající sady dává:

22 24

Extrahováním 22 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct 14 patnáct 17 19 22

a

24

Nahromadění zbývající sady dává:

24

Extrahováním 24 a jeho přidáním do nového seznamu získáte výsledky:

3 5 6 7 9 jedenáct 14 patnáct 17 19 22 24

a

- - -

Pole haldy je nyní prázdné. Všechny prvky, které měl na začátku, jsou nyní v novém poli (seznamu) a jsou seřazeny.

Algoritmus Heapsort

Ačkoli se čtenář v učebnicích mohl dočíst, že heapsort se skládá ze dvou fází, heapsort může být stále považován za sestávající z jedné fáze, která se iterativně zmenšuje z daného pole. S tím je algoritmus pro řazení pomocí heapsort následující:

  • Rozšiřte netříděný seznam.
  • Extrahujte první prvek haldy a vložte jej jako první prvek nového seznamu.
  • Rozšiřte zbývající seznam.
  • Extrahujte první prvek nové haldy a vložte jej jako další prvek nového seznamu.
  • Opakujte předchozí kroky v pořadí, dokud není seznam haldy prázdný. Nakonec se nový seznam seřadí.

Heapsort Časová složitost Správná

Jednostupňový přístup se používá k určení časové složitosti pro heapsort. Předpokládejme, že existuje 8 neseřazených prvků, které mají být seřazeny.

Možný maximální počet operací k nahromadění 8 prvky je 8 .
The možný maximální počet operací k nahromadění zbývajících 7 prvky je 7 .
The možný maximální počet operací k nahromadění zbývajících 6 prvky je 6 .
The možný maximální počet operací k nahromadění zbývajících 5 prvky je 5 .
The možný maximální počet operací k nahromadění zbývajících 4 prvky je 4 .
The možný maximální počet operací k nahromadění zbývajících 3 prvky je 3 .
The možný maximální počet operací k nahromadění zbývajících dva prvky je dva .
The možný maximální počet operací k nahromadění zbývajících 1 prvek je 1 .

Maximální možný počet operací je:

8 + 7 + 6 + 5 + 4 + 3 + dva + 1 = 36

Průměr těchto počtů operací je:

36 / 8 = 4.5

Všimněte si, že poslední čtyři hromady na předchozím obrázku se nezměnily, když byl odstraněn první prvek. Některé z předchozích hald se také nezměnily, když byl odstraněn první prvek. S tím je lepší průměrný počet hlavních operací (swappingů) 3 a ne 4,5. Takže lepší celkový průměrný počet hlavních operací je:

24 = 8 X 3
=> 24 = 8 X log < sub > dva < / sub > 8

od log dva 8 = 3.

Obecně je průměrná časová složitost pro heapsort:

Ó ( n. log2n )

Kde tečka znamená násobení an je N, celkový počet prvků v seznamu (v obou seznamech).

Všimněte si, že operace extrakce prvního prvku byla ignorována. U tématu časové složitosti jsou ignorovány operace, které trvají relativně krátkou dobu.

Kódování v C++

V knihovně algoritmů C++ existuje funkce make_heap(). Syntaxe je:

šablona < třída RandomAccessIterator, třída Porovnejte >
constexpr prázdnota vytvořit_hromadu ( RandomAccessIterator jako první, RandomAccessIterator jako poslední, Porovnat komp ) ;

Jako svůj první argument bere iterátor ukazující na první prvek vektoru a jako poslední argument pak iterátor ukazující těsně za konec vektoru. Pro předchozí neseřazený seznam by se syntaxe použila následovně, aby se získala minimální hromada:

vektor < int > vtr = { 9 , 19 , 24 , 5 , 3 , jedenáct , 14 , 22 , 7 , 6 , 17 , patnáct } ;
vektor < int > :: iterátor iterB = vtr. začít ( ) ;
vektor < int > :: iterátor iterE = vtr. konec ( ) ;
vytvořit_hromadu ( iterB, iterE, větší < int > ( ) ) ;

Tento kód změní vektorový obsah na konfiguraci minimální haldy. V následujících vektorech C++ budou místo dvou polí použity dva vektory.

Chcete-li zkopírovat a vrátit první prvek vektoru, použijte syntaxi vektoru:

constexpr referenční přední strana ( ) ;

Chcete-li odstranit první prvek vektoru a zahodit jej, použijte syntaxi vektoru:

constexpr vymazání iterátoru ( pozice const_iterator )

Chcete-li přidat prvek na zadní stranu vektoru (další prvek), použijte syntaxi vektoru:

constexpr prázdnota zatlačit zpátky ( konst T & X ) ;

Začátek programu je:

#include
#include
#include
použitím jmenný prostor std ;

Algoritmus a vektorové knihovny jsou zahrnuty. Další v programu je funkce heapsort(), což je:

prázdnota hepsort ( vektor < int > & oldV, vektor < int > & novýV ) {
-li ( starýV. velikost ( ) > 0 ) {
vektor < int > :: iterátor iterB = starýV. začít ( ) ;
vektor < int > :: iterátor iterE = starýV. konec ( ) ;
vytvořit_hromadu ( iterB, iterE, větší < int > ( ) ) ;

int další = starýV. přední ( ) ;
starýV. vymazat ( iterB ) ;
novýV. zatlačit zpátky ( další ) ;
hepsort ( staréV, novéV ) ;
}
}

Je to rekurzivní funkce. Používá funkci make_heap() knihovny algoritmů C++. Druhý segment kódu v definici funkce extrahuje první prvek ze starého vektoru po vytvoření haldy a přidá jej jako další prvek pro nový vektor. Všimněte si, že v definici funkce jsou parametry vektoru odkazy, zatímco funkce je volána s identifikátory (jmény).

Vhodná hlavní funkce C++ pro to je:

int hlavní ( int argc, char ** argv )
{
vektor < int > starýV = { 9 , 19 , 24 , 5 , 3 , jedenáct , 14 , 22 , 7 , 6 , 17 , patnáct } ;
vektor < int > novýV ;
hepsort ( staréV, novéV ) ;

pro ( int i = 0 ; i < novýV. velikost ( ) ; i ++ ) {
cout << novýV [ i ] << ' ' ;
}
cout << endl ;

vrátit se 0 ;
}

Výstup je:

3 5 6 7 9 jedenáct 14 patnáct 17 19 22 24

seřazeno (zcela).

Závěr

Článek podrobně pojednává o povaze a funkci Heap Sort běžně známého jako Heapsort jako třídícího algoritmu. Heapify Time Complexity, Heapsort ilustrace a Heapsort jako algoritmus byly pokryty a podpořeny příklady. Průměrná časová složitost dobře napsaného heapsortového programu je O(nlog(n))