2:8,7 3:9,4 / \ / \ / \ / \ 4:7,3 5:8 6:9,2 7:4

Podobne dokumenty
Sortowanie. Kolejki priorytetowe i algorytm Heapsort Dynamiczny problem sortowania:

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Algorytmy i struktury danych

Matematyka dyskretna - wykład - część Podstawowe algorytmy kombinatoryczne

Programowanie w VB Proste algorytmy sortowania

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Analiza algorytmów zadania podstawowe

prowadzący dr ADRIAN HORZYK /~horzyk tel.: Konsultacje paw. D-13/325

Algorytmy i struktury danych

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Algorytmy i Struktury Danych, 2. ćwiczenia

Sortowanie zewnętrzne

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Algorytmy i struktury danych Laboratorium Nr 4

Luty 2001 Algorytmy (7) 2000/2001

Algorytmy i Struktury Danych

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to

Strategia "dziel i zwyciężaj"

Sortowanie w czasie liniowym

Przykładowe B+ drzewo

Algorytmy sortujące i wyszukujące

Wstęp do programowania. Dziel i rządź. Piotr Chrząstowski-Wachtel

Definicja: Algorytmami sortowania zewnętrznego nazywamy takie algorytmy, które sortują dane umieszczone w pamięci zewnętrznej.

Zadania do wykonania. Rozwiązując poniższe zadania użyj pętlę for.

Porządek symetryczny: right(x)

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Poprawność semantyczna

1 Wprowadzenie do algorytmiki

Programowanie dynamiczne

Wstęp do informatyki. Maszyna RAM. Schemat logiczny komputera. Maszyna RAM. RAM: szczegóły. Realizacja algorytmu przez komputer

Informatyka 1. Przetwarzanie tekstów

Tadeusz Pankowski

Wstęp do programowania. Listy. Piotr Chrząstowski-Wachtel

Algorytmy i struktury danych. wykład 5

Laboratorium nr 7 Sortowanie

Algorytmy i. Wykład 5: Drzewa. Dr inż. Paweł Kasprowski

Rekurencje. Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie:

Sortowanie przez scalanie

Kompresja danych Streszczenie Studia Dzienne Wykład 10,

Informatyka 1. Wyrażenia i instrukcje, złożoność obliczeniowa

Sortowanie przez wstawianie Insertion Sort

Poszukiwanie liniowe wśród liczb naturalnych

Programowanie proceduralne INP001210WL rok akademicki 2017/18 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wykład 3. Metoda dziel i zwyciężaj

Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

Algorytm selekcji Hoare a. Łukasz Miemus

Wykład 2. Poprawność algorytmów

Wstęp do programowania. Różne różności

procesów Współbieżność i synchronizacja procesów Wykład prowadzą: Jerzy Brzeziński Dariusz Wawrzyniak

Algorytmy i Struktury Danych. (c) Marcin Sydow. Sortowanie Selection Sort Insertion Sort Merge Sort. Sortowanie 1. Listy dowiązaniowe.

Uwaga: Funkcja zamień(a[j],a[j+s]) zamienia miejscami wartości A[j] oraz A[j+s].

Algorytmy równoległe. Rafał Walkowiak Politechnika Poznańska Studia inżynierskie Informatyka 2010

wykład Organizacja plików Opracował: dr inż. Janusz DUDCZYK

Sortowanie bąbelkowe

Sortowanie - wybrane algorytmy

Sortowanie. Bartman Jacek Algorytmy i struktury

Algorytmy i Struktury Danych.

Algorytmy równoległe: ocena efektywności prostych algorytmów dla systemów wielokomputerowych

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy i Struktury Danych.

ALGORYTMY I STRUKTURY DANYCH

Algorytmy i Struktury Danych, 2. ćwiczenia

Algorytmy i struktury danych. Wykład 4 Tablice nieporządkowane i uporządkowane

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Informatyka A. Algorytmy

Sortowanie. LABORKA Piotr Ciskowski

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja, - liczby losowe

Wykład 1_2 Algorytmy sortowania tablic Sortowanie bąbelkowe

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0,

Algorytmy w teorii liczb

Analiza algorytmów zadania podstawowe

Zestaw 1 ZESTAWY A. a 1 a 2 + a 3 ± a n, gdzie skªadnik a n jest odejmowany, gdy n jest liczb parzyst oraz dodawany w przeciwnym.

Metodyka i Technika Programowania 1

Jeszcze o algorytmach

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2014/2015. Drzewa BST c.d., równoważenie drzew, kopce.

Technologie informacyjne Wykład VII-IX

Wstęp do programowania

Kolejka priorytetowa. Często rozważa się kolejki priorytetowe, w których poszukuje się elementu minimalnego zamiast maksymalnego.

Sortowanie Shella Shell Sort

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

Programowanie w Turbo Pascal

Zaawansowane algorytmy i struktury danych

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Haszowanie (adresowanie rozpraszające, mieszające)

Rekurencja. Przykład. Rozważmy ciąg

Algorytmy i struktury danych. Wykład 6 Tablice rozproszone cz. 2

Wykład 6. Metoda eliminacji Gaussa: Eliminacja z wyborem częściowym Eliminacja z wyborem pełnym

Instrukcje podsumowanie. Proste: - przypisania - wejścia-wyjścia (read, readln, write, writeln) - pusta - po prostu ; (średnik) Strukturalne:

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

Temat: Algorytm kompresji plików metodą Huffmana

PLAN WYKŁADU BAZY DANYCH INDEKSY - DEFINICJE. Indeksy jednopoziomowe Indeksy wielopoziomowe Indeksy z użyciem B-drzew i B + -drzew

Programowanie Proceduralne

Algorytm. a programowanie -

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

Wstęp do programowania

Algorytmy i złożoność obliczeniowa. Wojciech Horzelski

Podstawy Informatyki. Sprawność algorytmów

Transkrypt:

Wykład: Sortowanie III Drzewa Turniejowe 1:9,8 2:8,7 3:9,4 4:7,3 5:8 6:9,2 7:4 8: 3 9:7 12:9 13:2 Insert(x,S) 1) tworzymy dwa nowe liście na ostatnim poziomie, 2) do jednego wstawiamy x a do drugiego wartość z liścia, np. val(i), z poziomu sąsiedniego, 3) oba liście stają się następnikami i, 4) aktualizujemy wartości na ścieżce do korzenia.

Insert(5,S) 1:9,8 2:8,7 3:9,4 4:7,3 5:8 6:9,2 7:?,? 8: 3 9:7 12:9 13:2 14:4 15:5 1:9,8 2:8,7 3:9,5 4:7,3 5:8 6:9,2 7:5,4 8: 3 9:7 12:9 13:2 14:4 15:5

Deletmax(S): 1:9,8 2:8,7 3:9,5 4:7,3 5:8 6:9,2 7:5,4 8: 3 9:7 12:9 13:2 14:4 15:5 1) usuwamy liść zawierający największy element (mx(1)), 2) jeśli mx(1) nie należy do ostatniego poziomu, to w jego miejsce wstawiamy dowolny element z ostatniego poziomu mniejszy od sąsiada, 3) aktualizujemy wartości na ścieżce od mx(1) do korzenia.

1:9,8 2:8,7 3:9,5 4:7,3 5:8 6:2 7:5,4 8: 3 9:7 14:4 15:5 Po usunięciu największego elementu. 1:8,5 2:8,7 3:5,2 4:7,3 5:8 6:2 7:5,4 8: 3 9:7 14:4 15:5 Po aktualizacji.

1:8,5 2:8,7 3:5,2 4:7 5:3 6:2 7:5,4 14:4 15:5 Po usunięciu największego elementu. 1:7,5 2:7,3 3:5,2 4:7 5:3 6:2 7:5,4 14:4 15:5 Po aktualizacji. T_deletmax = log n - 1 = O(log n)

Sortowanie pozycyjne Binarna reprezentacja danych w komputerze nie jest brana pod uwagę w ogólnych algorytmach sortowania. Również w językach programowania wysokiego poziomu nie ma operacji na liczbach binarnych. function bits(x, k, j : integer): integer, bits := (x div 2 k ) mod 2 i end bits; Funkcja bits wycina j bitów, poczynając od bitu o numerze k z prawej strony.

Sortowanie pozycyjnego - metoda liczników częstości. Załóżmy, że b = 2 n. Dla każdego j = 0, l,...,b - l liczymy, ile razy j pojawia się w ciągu wejściowym a[1],...,a[n]. Na podstawie obliczonych liczników częstości umieszczamy każdy element tablicy a, we właściwym miejscu w ciągu wynikowym.

procedure countsort, {a[l.. n]. t[l.. n]. count[0.. m -l]} var i, j, p: integer; for j := 0 to m-l do count[j] := 0; {inicjowanie} for i := 1 to n do count[a[i]] := count[a[i]] + 1; {count[j] to liczba wystąpień liczby j} for j := 1 to m-l do count[j] := count[j-1] + count[j]; {count[j] to liczba wystąpień elementów <= j} for i := n downto l do p:= a[i]; t[count[p]] := p; count[p] := count[p] - 1 end; for i := 1 to n do a[i] := t[i] end countsort;

Przykład: q = [1,3,1,2,2,1,3] 1sza iteracja 2ga iteracja count[1] = 3, count[2] = 2, count[3] = 2, 3cia iteracja count[1] = 3, count[2] =5, count[3] = 7, 1szy element zajmie pozycje a[1...count[1]] 2gi element zajmie pozycje a[count[1]+1...count[2]] 3ci element zajmie pozycje a[count[2]+1...count[3]] Wypisywanie elementów do tablicy - - - - - - 3 - - 1- - - 3 - - 1-2- 3 - - 122-3 - 1122-3 - 112233 1112233

Analiza -algorytmu countsort jest bezpośrednia: T(n, m) = A(n, m) = O(n + m) S(n, m) = n + m + 0(1) Algorytm jest szybki, gdy m = O(n) Algorytm jest stabilny. Countsort można stosować tylko dla niedużych wartości m (tablica count ma rozmiar m!). Dla większych wartości m można stosować podobną metodę, ale z dzieleniem liczb do posortowania na części, na których algorytm countsort może działać.

Dzielimy słowa o b bitach na b/e grup e bitowych. 1) sortujemy ciąg liczb, stosując algorytm countsort względem ostatniej (najmniej znaczącej) grupy bitów. 2) sortujemy ciąg liczb względem przedostatniej grupy bitów, itd. b/e) sortujemy ciąg liczb względem pierwszej grupy bitów. Istotna jest stabilność algorytmu countsort. O pozycji elementu decyduje pierwszych e bitów; jeśli są one takie same, to decydujące znaczenie mają dopiero następne grupy bitów, które zostały też posortowane.

procedure radixsort; {m=2 e, a, t[l.. n],count[0.. m-l]} var i, j, pass, nofpasses, key: integer; nofpasses := b div e; if nofpasses * e := b then nofpasses := nofpasses - 1; for pass: = 0 to nofpasses do for j :=0 to m-1 do count[j] :=0; for i : = l to n do key := bits(a[i], pass*e, e); count[key] := count[key] + 1 end; for j:=1 to m-l do count[j]:= count[j-1] + count[j]; for i := n downto 1 do key:= bits(a[i], pass * e, e); t[count[key]] := a[i]; count[key] := count[key]-l end; for i := 1 to n do a[i] := t[i] end end radixsort; T(n,m) = A(n,m) = O(n+m), gdy b/e = O(1) S(n,m) = n+m+o(1)

Przykład: b = 8, e = 2, n = 4 a[l] = 011100 10 a[2] = 110111 01 a[3] = 100000 00 a[4] = 011010 01 pass = 0 a[l] = 1000 00 00 a[2] = 1101 11 01 a[3] = 0110 10 01 a[4] = 0111 00 10 pass = 1 a[l] = 1000 00 00 a[2] = 0111 00 10 a[3] = 0110 10 01 a[4] = 1101 11 01 pass = 2 a[l] = 10 00 00 00 a[2] = 11 01 11 01 a[3] = 01 10 10 01 a[4] = 01 11 00 10

pass = 3 a[l] = 01 10 10 01 a[2] = 01 11 00 10 a[3] = 10 00 00 00 a[4] = 11 01 11 01

Zalety Radixsort: Liniowa złożoność czasowa przy odpowiednich założeniach dotyczących n, tzn. m = O(n). Dla średnich wartości n Radixsort może być szybszy niż quicksort. Po modyfikacjach może być użyty do sortowania: słów w porządku alfabetycznym liczb rzeczywistych z pewnego przedziału Wady: Algorytm jest wolny dla małych rozmiarów n, Duże zużycie pamięci dla dużych n.

Sortowanie tablic przez łączenie: Mamy dany ciąg rekordów: r 1,..., r n typu type rek = rekord klucz : typ_klucza; pole_1: typ_pola_1;... pole_m : typ_pola_m end Zakładamy, że typ_klucza jest uporządkowany liniowo (np. tak jak jest dla typów prostych). Naszym zadaniem jest takie przestawienie elementów ciągu tak, by otrzymany ciąg r p1,..., r pn miał własność: r p1.klucz <=...<= r pn.klucz Idea algorytmu polega na tym, że ciąg dzieli się na uporządkowane fragmenty r i,..., r j spełniające: r k.klucz <= r k+1.klucz dla k=i,...,j-1 r k-1.klucz > r k.klucz dla k=i, r k.klucz > r k+1.klucz dla k=j Ciągi r i,...,r j będziemy nazywać seriami.

Rozważmy ciąg: 43, 18, 21, 30, 13, 52, 51, 75, 80, 62 zawiera następujące serie: 43 18, 21, 30 13, 52 51, 75 80 62 Po zdefiniowaniu serii wybieramy dwie serie, np. 18, 21, 30 13, 52 łącząc je otrzymujemy nową serię w następujący sposób: 13 18, 21, 30 52 13,18 21, 30 52 13,18,21 30 52 13, 18, 21,30 52 13, 18, 21,30,52

Na tej podstawie można ułożyć następujący algorytm (oznaczmy go *): dane są dwie tablice x: array[1..m] of rek y: array[1..n] of rek. Rezultatem ich łączenia jest z: array[1..n+m] of rek Algorytm abstrakcyjny tej operacji jest następujący: ustal wartości początkowe indeksów; while (i<=m) and (j<=n) do if element serii x <= elementu serii y then dopisz do tablicy z element serii x zwiększ indeks tablicy x i z end else dopisz do tablicy element serii y zwiększ indeks tablicy y i z end end dołączenie końca serii x; dołączenie końca serii y

Rozwijając poszczególne instrukcje abstrakcyjne możemy otrzymać następujący program: i:=1; j:=1; k:=1; while (i<=m) and (j<=n) do if x[i].klucz<=y[j].klucz then z[k]:=x[i]; k:=k+1; i:=i+1 end else z[k]:=y[j]; k:=k+1; j:=j+1 end end dołączenie końca serii x; dołączenie końca serii y; Uściślenie operacji dołączania końca jest następujące: {dołączenie końca serii x;} while i <=m do z[k]:=x[i]; k:=k+1; i:=i+1; end; {dołączenie końca serii y} while j<=n do z[k]:=y[j]; k:=k+1; j:=j+1; end;

Czyli powinniśmy łączyć coraz dłuższe serie, aż do otrzymania dwóch serii, a połączenie tych serii da jeden ciąg posortowany. Sugeruje to następującą ideę: mamy ciąg danych, wybieramy dwie serie łączymy je ze sobą, powtarzamy operacje aż będzie jedna seria. Za pomocą abstrakcyjnego algorytmu możemy zapisać to następująco: repeat Podział ciągu; Łączenie ciągów until jedna seria Należy zauważyć, że ciągi mogą być w postaci tablicy, listy lub plików. Rozważamy tablice, ale sam algorytm będzie zależał od reprezentacji. Ponieważ dane są zapisane w tablicy, to możemy uzyskiwać bardzo łatwo do nich dostęp. Niech tablica będzie postaci: a : array[1..n] of rek.

Jako serie możemy wybierać dowolne ciągi, ale najlepiej będzie wybierać ciągi z początku tablicy i z końca. Połączone serie będą umieszczone w tablicy a takiego samego typu jak i tablica a. Proces łączenia można przedstawić następująco na przykładzie: 43 18 21 30 13 52 51 75 80 62 a 43 62 80 13 51 52 75 30 21 18 a 18 21 30 43 62 75 80 52 51 13 a 13 18 21 30 43 51 52 62 75 80 a 13 18 21 30 43 51 52 62 75 80 a Wprowadzając te ustalenia otrzymujemy następujący abstrakcyjny algorytm: apa :=false; repeat Ustawienie początkowe i,j,k,p; m:=0 {liczba utworzonych serii} Łączenie serii od i,j do k,p; apa=not apa until m=1 if apa then kopiowanie a do a apa przełącznik mówiący o tym, że gdy apa = true to przenosimy dane z a do a i gdy apa = false to przenosimy w odwrotnym kierunku,

Powyższy algorytm może być realizowany za pomocą jednej tablicy A, ale mającej dwa razy większy rozmiar. Pierwsza część tablicy odpowiada za tablicę a[1..n], a druga za tablicę a = a[n+1..2*n]. Przy tych założeniach {Ustawienie początkowe i,j,k,p} można uściślić następująco: if apa then i:=1; j:=n; k:=n+1; p:=2*n end else k:=1; p:=n; i:=n+1; j:=2*n end; Natomiast instrukcję {Łączenie serii od i,j do k,p} można wyrazić jako instrukcję iteracyjną, w której podstawową czynnością w każdym powtórzeniu jest łączenie dwóch serii w jedną. Elementy wybiera się z punktów określonych przez i oraz j, a umieszcza się w na przemian w punktach określonych przez k i p. Można tak postąpić, by program zawsze umieszczał elementy w miejscu określonym przez k. W tym celu należy zamieniać wartości k i p po połączeniu dwóch serii oraz określić kierunek zmian indeksu (gdy dodajemy do oryginalnej

wartości k to zwiększamy o +1 a gdy do p to o 1). Wprowadzamy zmienną h. h:=1; repeat łączenie serii od i,j w jedną k; h:=-h; m:=m+1; zamiana k i p; until i=j Uściślenie instrukcji zamiana k i p; polega na następujących czynnościach: t:=k; k:=p; p:=t Natomiast uściślenie instrukcji łączenie serii od i,j w jedną k; jest podobne do algorytmu (*) i można zapisać następująco: {łączenie serii od i,j w jedną k;} repeat if A[i].klucz<A[j].klucz then A[k]:=A[i]; i:=i+1; kons:=a[i-1].klucz > A[i].klucz (**) end else A[k]:=A[j]; j:=j-1; kons:=a[j+1].klucz > A[j].klucz

end k:=k+h until kons Dołączenie końca serii od i; Dołaczenie końca serii od j Gdzie kons jest zmienną, która określa, czy został osiągnięty koniec serii. Jeżeli dojdziemy do końca serii, to przerywamy pętlę repeat. Operacje dołączania końca serii mogą być zapisane następująco (użyto w nich pętli while aby operacja dołączania serii była pomijana gdy koniec jest pusty). {dołączenie końca serii od i} while A[i].klucz <= A[i+1].klucz do A[k]:=A[i]; k:=k+h; i:=i+1 end {dołączenie końca serii od j} while A[j].klucz<=A[j-1].klucz do A[k]:=A[j]; k:=k+h; j:=j-1 end

Należy zauważyć, że w algorytmie (**) przy przetwarzaniu ostatniego elementu danej serii wskaźnik przesunie się do nowej serii. Tak więc przesuwanie powinno być wykonywane warunkowo, gdy nie został osiągnięty koniec serii (koniec serii jest wtedy, gdy zmienna kons ma wartość true). Poprawiony algorytm jest więc postaci: {łączenie serii od i,j w jedną k;} repeat if A[i].klucz<A[j].klucz then A[k]:=A[i]; if A[i].klucz > A[i+1].klucz then kons:=true else i:=i+1; end else (poprawiony **) A[k]:=A[j]; j:=j-1; if A[j].klucz > A[j-1].klucz then kons:=true else j:=j-1; end k:=k+h until kons Dołączenie końca serii od i; Dołaczenie końca serii od j

Podany algorytm nie działa jeszcze poprawnie. Mianowicie w sytuacji, gdy serie zachodzą na siebie to pewne elementy mogą być dwukrotnie skopiowane. Aby tego uniknąć, należy zmodyfikować następująco odpowiednie instrukcje: {dołączenie końca serii od i} while (A[i].klucz<=A[i+1].klucz) and (i<j)do A[k]:=A[i]; k:=k+h; i:=i+1 end {dołączenie końca serii od j} while (A[j].klucz<=A[j-1].klucz) and (i<j) do A[k]:=A[j]; k:=k+h; j:=j-1 end Natomiast instrukcja kopiowanie z a do a jest postaci: for i:=1 to n do A[i]:=A[i+n];

Sortowanie zewnętrzne Elementy znajdują się w pliku zewnętrznym i do bufora pamięci wewnętrznej można zapisać maksymalnie m elementów. Przez blok lub serię rozumiemy dowolną posortowaną część listy. Algorytmy sortowania zewnętrznego składają się z dwóch głównych kroków: 1) tworzenia bloków początkowych, 2) scalania wielofazowego tak długo aż pozostanie tylko jeden blok.

Scalanie wielofazowe z 4 plikami Bloki zostały równo rozłożone na pliki P_0 i P_1. Pliki P_2 i P_3 są początkowo puste. i1 := 0, i2 := 1 {otwarte do czytania} j1 := 2, j2 := 3 {otwarte do pisania} while jest więcej niż jeden blok do 1) scal pierwszy blok z P_i1 z pierwszym z P_i2 i zapisz do P_j1, 2) scal następny blok z P_i1 z następnym z P_i2 i zapisz do P_j2, 3) powtarzaj 1) i 2) aż do końca plików P_i1 i P_i2, 4) przewiń pliki do początku, dodaj 2 mod 4 do i1,i2,j1,j2, zamieniając role plików wejściowych i wyjściowych. Algorytm wymaga log(n/m) faz, gdzie n liczba elementów m liczba elementów w bloku

Scalanie wielofazowe z 3 plikami Mamy do dyspozycji trzy pliki: P_0, P_1, P_2. P_0 zawiera F_k bloków a P_1 F_k+1 bloków, Gdzie F_k to k-ta liczba Fibonacciego. F_0 = 0 F_1 = 1 F_k+1 = F_k-1+ F_k dla k > 1 i1 := 0; i2 := 1 {pliki wejściowe} j := 2 {plik wyjściowy} while jest więcej niż jeden blok do 1) scal pierwszy blok z P_i1 z pierwszym z P_i2 i zapisz do P_j, 2) powtarzaj 1) aż do końca pliku P_i1, 3) przewiń pliki P_i1 i p_j do początku, dodaj 1 mod 3 do i1,i2,j. Złożoność: 1.04nlog(n/m) + O(n) porównań 2 * 1.04nlog(n/m) + O(n/m) przesłań

Przykład: P0: 8 P1: 13 P2: P0: P1: 5 P2: 8 P0: 5 P1: P2: 3 P0: 2 P1: 3 P2: P0: P1: 1 P2: 2 P0: 1 P1: P2: 1 P0: P1: 1 P2:.