Privacy Policy Cookie Policy Terms and Conditions Sortowanie przez kopcowanie - Wikipedia, wolna encyklopedia

Sortowanie przez kopcowanie

Z Wikipedii

Sortowanie kopcem (ang. heapsort) - zwane też inaczej sortowaniem przez kopcowanie. Algorytm ten jest jedną z ciekawszych metod sortowania z racji faktu, iż jest on szybki oraz nie pochłania zbyt wiele zasobów pamięci. Jego złożność czasowa to O(n log n), a pamięciowa O(1). Algorytm ten jest nieco wolniejszy od sortowania szybkiego, lecz ma lepszą pesymistyczną złożoność czasową. Sortowanie przez kopcowanie jest niestabilne, co może być czasami uznawane za wadę. Do jego wad można też zaliczyć fakt, iż jest on stosunkowo skomplikowany w implementacji.

Spis treści

[edytuj] Opis algorytmu

Podstawą algorytmu jest użycie kolejki priorytetowej zaimplementowanej w postaci binarnego kopca zupełnego. Szczegóły implementacji kopca wyjaśnione są w artykule kopiec. Zaletą kopca jest to, że oprócz stałego czasu dostępu do elementu maksymalnego (lub minimalnego) oferuje on logarytmiczny czas wstawiania i usuwania elementów. Ponadto kopiec można łatwo implementować w postaci tablicy.

Algorytm sortowanie przez kopcowanie składa się z dwóch faz. W pierwszej sortowane elementy reorganizowane są w celu utworzenia kopca. W drugiej zaś dokonywane jest właściwe sortowanie.

[edytuj] Tworzenie kopca

Podstawową zaletą algorytmu jest to, że do stworzenia kopca wykorzystać można tę samą tablicę, w której początkowo znajdują się nieposortowane elementy. Dzięki temu uzyskuje się stałą złożność pamięciową.

Początkowo do kopca należy tylko pierwszy element w tablicy. Następnie kopiec rozszerzany jest o drugą, trzecią i kolejne pozycje tablicy, przy czym przy każdym rozszerzeniu, nowy element jest przemieszczany w górę kopca, tak aby spełnione były relacje pomiędzy węzłami. Schematycznie wygląd sortowanej tablicy można przedstawić w następujący sposób:

 -----------------------------------------------------------
| Kopiec  | Reszta nieposortowanych elementów               |
 -----------------------------------------------------------

a kopiec rozrasta się, aż do wyczerpania nieposortowanej części tablicy.

Dzięki logarytmicznej złożoności pojedynczych operacji wstawiania (rozszerzania kopca), całkowita złożoność tego etapu to O(nlog n).

Można też ten krok wykonać szybciej - w czasie O(n). W tym celu należy budować kopiec w następujący sposób:

 -----------------------------------------------------------
| Reszta nieposortowanych elementów        | Małe kopce    |
 -----------------------------------------------------------

Aby osiągnąć taką strukturę, wystarczy pierwsze n div 2 elementów tablicy (zakładając, że kopiec implementujemy w tablicy) przesunąć w dół kopca procedurą shift-down:

shift-down (T[1..n], i)
    k ← i
    repeat
        j ← k
        if 2 * j <= n and T[2 * j] > T[k]
            k ← 2 * j
        if 2 * j + 1 <= n and T[2 * j + 1] > T[k]
            k ← 2 * j + 1
    until j = k

Zatem procedura budująca kopiec wyglądałaby następująco:

build-heap (T[1..n])
    for i ← n div 2 downto 1
        shift-down (T, i)

Procedura build-heap buduje kopiec w czasie O(n).

[edytuj] Sortowanie

Po utworzeniu kopca następuje właściwe sortowanie. Polega ono na usunięciu wierzchołka kopca, zwierającego element maksymalny (minimalny), a następnie wstawieniu w jego miejsce elementu z końca kopca i odtworzenie porządku kopcowego. W zwolnione w ten sposób miejsce, zaraz za końcem zmniejszonego kopca wstawia się usunięty element maksymalny. Operacje te powtarza się aż do wyczerpania elementów w kopcu. Wygląd tablicy można tu schematycznie przedstawić następująco:

 -----------------------------------------------------------
| Kopiec elementów do posortowania | Posortowana tablica    |
 -----------------------------------------------------------

Tym razem kopiec kurczy się, a tablica przyrasta (od elementu ostatniego do pierwszego).

Także, tu złożoność usuwania elementu połączonego z odtwarzaniem porządku kopcowego, ma złożoność logarytmiczną, a zatem złożoność tej fazy to O(nlog n).

[edytuj] Porównanie z innymi algorytmami sortowania

Algorytm sortowania przez kopcowanie jest na ogół nieco wolniejszy niż Sortowanie Szybkie. Jego przewagą natomiast jest lepsza złożność pesymistyczna wynosząca O(n log n), podzas gdy dla quicksort jest to O(n2), co jest nie do przyjęcia, dla dużych zbiorów danych. Także złożność pamięciowa O(1) jest lepsza niż Ω(log n) alorytmu quicksort.

Heapsort jest nieco szybszy od algorytmu mergesort, mającego taką samą asympotyczną złożoność czasową. Mergesort wymaga jednak Ω(n) dodatkowej pamięci. Zaletą mergesort jest prostsza definicja i lepsze zachowanie w przypadkach, gdy dane do sortowania pobierane są z wolnej pamięci masowej; jest też łatwiejszy do zrównoleglenia.

[edytuj] Przykład implementacji

Przykładowa implementacja w C++ (GCC):

#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>

using namespace std;

void fixHeap(vector<int>& v1);
void fixNode(vector<int>& v1, unsigned int node);
void showVec(const vector<int>& v1);


int main()
{
        vector<int> v1(1,999);
        vector<int> sorted(1,999);
        vector<int>::iterator it;

        srand(time(0)); // inicjalizacja rand'a


       
                v1.push_back(rand() % 20); 

        showVec(v1);
        cout << endl;

// realizacja algorytmu
        fixHeap(v1);

        for (int i = v1.size(); i > 1 ;i--) {
                sorted.push_back(v1[1]);
                v1[1] = v1.back();
                v1.pop_back();
                fixNode(v1, 1);
        }

        showVec(sorted);
        return 0;
}

void showVec(const vector<int>& v1)
{
        for (int i = 1; i < v1.size(); i++)
                cout << v1[i] << endl;
}

void fixNode(vector<int>& v1, unsigned int node)
{
        int left = node*2;
        int right = node*2 + 1;

        int max = node;

        if ( v1.size() > left && v1[max] < v1[left] )
                max = left;
        if ( right < v1.size() && v1[right] > v1[max] )
                max = right;

        if ( max != node ) {
                swap(v1[node], v1[max]);
                fixNode(v1, max);
        }
}

void fixHeap(vector<int>& v1)
{
        for (int i = v1.size()/2; i > 0; i--)
                fixNode(v1, i);
}


[edytuj] Przykład implementacji, napisanej dla 10 liczb wprowadzanych z klawiatury

#include <iostream>
#include <iomanip>
using namespace std;

int main(){
  int n=10,tab[10];
  cout<< "Wprowadz elementy do posortowania:";
  for (int i=1;i<=10;i++){
      cin>>tab[i];
      }
  int i,j,k,m,x;
  for(i=0;i<=n;i++){
    j=i; 
    k=j/2;
    x = tab[i];
    while((k>0) && (tab[k]<x)){
    tab[j] = tab[k];
    j = k; k = j / 2;
    }
    tab[j] = x;
  }
  for(i = n; i > 1; i--)
  {
    swap(tab[1], tab[i]);
    j = 1; k = 2;
    while(k < i)
    {
      if((k + 1 < i) && (tab[k + 1] > tab[k]))
        m = k + 1;
      else
        m = k;
      if(tab[m] <= tab[j]) break;
      swap(tab[j], tab[m]);
      j = m; k = j + j;
    }
  }
  cout << "Po sortowaniu:\n\n";
  for(i = 1; i <= n; i++){ 
  cout<<tab[i]<<" ";
  }
system("PAUSE");
return EXIT_SUCCESS;
}
THIS WEB:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2006:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu