× Aktuálně z oboru

Programátoři po celém světě dnes slaví Den programátorů [ clanek/2018091300-programatori-po-celem-svete-dnes-slavi-den-programatoru/ ]
Celá zprávička [ clanek/2018091300-programatori-po-celem-svete-dnes-slavi-den-programatoru/ ]

VB - 44. lekce

[ http://programujte.com/profil/27-jiri-chytil/ ]Google [ ?rel=author ]       [ http://programujte.com/profil/118-zdenek-lehocky/ ]Google [ ?rel=author ]       29. 6. 2006       17 205×

44.1 Třídění přetřásáním (ShakeSort)
44.2 Rychlé třídění (QuickSort)
44.3 Třídění haldou (HeapSort)
44.4 Domácí úkol
44.5 V další lekci

44.1 Třídění přetřásáním (ShakeSort)

ShakeSort je prakticky stejný jako BubbleSort, ovšem je dvousměrný, to znamená, že v jednom průběhu se třídí jednou ze začátku pole a potom od jeho konce. Doba potřebná pro seřazení se zkrátí více jak o polovinu.

start:
    Change = False
    For i = 0 To lngVelikostPole - 1
        If pole(i) > pole(i + 1) Then
            temp = pole(i)
            pole(i) = pole(i + 1)
            pole(i + 1) = temp
            Change = True
        End If
    Next i
        
    If Change Then
        Change = False
        For i = lngVelikostPole To 1 Step -1
            If pole(i) < pole(i - 1) Then
                temp = pole(i)
                pole(i) = pole(i - 1)
                pole(i - 1) = temp
                Change = True
            End If
        Next i
    End If
If Change Then GoTo start

44.2 Rychlé třídění (QuickSort)

QuickSort je jeden z nejrychlejších algoritmů na třídění, má ovšem jednu nevýhodu, při zvolení špatného pivotu se jeho výkon extrémně sníží. Funkce je rekurzivní, volá sama sebe. O rekurzi se budeme bavit hned, jak bude v lekcích volno. Teď jí tedy proběhnu jen zběžně. Jde o to, že algoritmus si vybere jeden prvek – pivot. Podle něj rozdělí pole na dvě části, v jedné části se budou nacházet ty prvky, které mají hodnotu menší, než je pivot, a ve druhé části budou prvky s hodnotou větší nebo stejnou. No a totéž se opakuje pro ta dvě pole, ta se také rozdělí – každé na dvě části podle pivotu. A každé z nich se zase rozdělí na další menší kousky až je celé pole setřízené. Třídění je zakončeno poté, co již nelze pole dělit, tedy velikost jednotlivých vzniklých polí je jeden prvek. Jako pivot se volí nejčastěji první prvek pole, které vstupuje do funkce QuickSort. Projedeme si to tedy ještě jednou: Mějme pole například o 10 prvcích. Pole vložíme do funkce QuickSort a vzniknou nám rozdělením dvě další pole, ta se rozdělí podle pivotu (nejvhodnější by pro nás bylo, aby se pole rozdělilo na dvě rovnoměrné části, to ale nemusí být pravidlem, a tudíž zvolíme-li si pole např. 1 000 prvků a ono se nám rozdělí na pole 7 a 992 + pivot (ten již budeme připočítávat automaticky) a pak na 3 a 4 a druhé se rozdělí 973 a 19, pak rychlost klesá. Pokud se ale pole rozdělí na 529 a 470 a pak na 233 a 296 a druhé na 235 a 235, bude situace jiná a třídění bude rychlejší. No ale je načase ukončit tento dlouhý text v závorce.) třeba na dvě pole 4 a 6 prvků. Každé z těchto polí projde dalším rozdělením na další dvě, ale z polí je vyjmut pivot, takže např. na 1 a 2 prvky v případě prvního pole a na 1 a 4 prvky v případě druhého. Tak to pokračuje dál a dál až všechna pole obsahují jen jediný prvek.

Public Sub QSort(pole As Variant, indexD As Long, indexH As Long)
   Dim pivot   As Variant
   Dim tmpSwap As Variant
   Dim indexD0  As Long
   Dim indexH0   As Long
    
   indexD0 = indexD 'přesun dat to pomocných porměnných
   indexH0 = indexH
   
   pivot = pole((indexD + indexH) \ 2) 'volba pivotu
   
   While (indexD0 <= indexH0)
      While (pole(indexD0) < pivot And indexD0 < indexH) 'roztřídění tabulek vzhledem k pivotu
         indexD0 = indexD0 + 1
      Wend
      
      While (pivot < pole(indexH0) And indexH0 > indexD)
         indexH0 = indexH0 - 1
      Wend
      
      If (indexD0 <= indexH0) Then
         tmpSwap = pole(indexD0)
         pole(indexD0) = pole(indexH0)
         pole(indexH0) = tmpSwap
         indexD0 = indexD0 + 1
         indexH0 = indexH0 - 1
      End If
   Wend
   
   If (indexD < indexH0) Then QuickSortVariants pole, indexD, indexH0 'rekurzivní volání pro nově vzniklá pole
   If (indexD0 < indexH) Then QuickSortVariants pole, indexD0, indexH
End Sub

44.3 Třídění haldou (HeapSort)

No a jako poslední třídící algoritmus v této lekci bude HeapSort. Je to velmi rychlý algoritmus, mezi jeho výhody patří také to, že neobsahuje žádné rekurze. To pro nás zaznamená nižší nároky na paměť. Jeho další výhodou, oproti mírně rychlejšímu QuickSortu, je stabilita výkonu.

No než se začneme zabývat tříděním jako takovým, myslím, že by nebylo od věci vysvětlit, co je to ona halda nebo též hromada – anglicky heap. Je to binární strom, ve kterém platí určitá pravidla. Je jich několik a jejch tvar je jakoby pyramida, která může být z jedné strany nekompletní, a to pouze v poslední řadě prvků. Jeden z prvků tedy tvoří vrchol haldy, ten má dva, řekněme, syny a každý z nich má další dva potomky a ty myjí další dva potomky. Pokud je ale počet prvků menší a nevyjde tedy počet prků na to, aby každý mateřský prvek měl dva potomky (tedy krom spodní řady, jinak bychom se dostali do nekonečna), tak poslední z prvků v předposlední řadě nebude mít potomky. Důležité ja pak také to, že každý z prvků je menší nebo roven svým následovníkům. Pokud tedy bude mateřský prvek 12 a potomci budou 6 a 9, tak je to v pořádku.

Třídění pomocí haldy se skládá ze dvou částí; první je přidání nového prvku. Ten se přidá na první volné místo úplně vespod haldy. A poté se porovnává se svými rodiči a v případě, že hodnoty nesplňují pravidla, prvky se přehodí a to se děje tak dlouho, dokud tato pravidla nejsou splněna nebo dokud prvek nedosáhne vrcholu haldy, ten totiž nemá žádné rodičovské prvky. Tím bychom měli první část programu hotovou, tedy stavbu haldy; teď nás čeká druhá část, tou je rozebírání haldy. To se provádí, dá se říci, probubláváním. Odebereme kořenový prvek, tedy ten z nejvyššího místa haldy, a postupně necháváme ostatní prvky probublávat výš. Takto se pokračuje do té doby, než se strom vyprázdní.

44.4 Domácí úkol

Za domácí úkol rozšíříte program který jste vytvořili minule o tyto tři nové algoritmy.

44.5 V další lekci

Třídění pomocí: ShellSort, RadixSort a MergeSort.


Článek stažen z webu Programujte.com [ http://programujte.com/clanek/2006062602-vb-44-lekce/ ].