Podstawy programowania. Przykłady algorytmów Cz. 2 Sortowanie

Podobne dokumenty
Struktury Danych i Złożoność Obliczeniowa

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

Sortowanie w czasie liniowym

INFORMATYKA SORTOWANIE DANYCH.

Podstawy programowania. Podstawy C# Przykłady algorytmów

Algorytm i złożoność obliczeniowa algorytmu

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Analiza algorytmów zadania podstawowe

Zasady analizy algorytmów

Algorytmy i Struktury Danych.

Algorytmy i struktury danych Sortowanie IS/IO, WIMiIP

Programowanie w VB Proste algorytmy sortowania

Sortowanie. Bartman Jacek Algorytmy i struktury

Strategia "dziel i zwyciężaj"

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 )

Algorytmy sortujące i wyszukujące

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

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

Sortowanie przez scalanie

Wstęp do programowania

Algorytmy i Struktury Danych, 2. ćwiczenia

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

Laboratorium nr 7 Sortowanie

Matematyczne Podstawy Informatyki

Sortowanie - wybrane algorytmy

Sortowanie bąbelkowe

Algorytmy i struktury danych

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Podstawy Informatyki. Sprawność algorytmów

Zaawansowane algorytmy i struktury danych

Wykład 2. Poprawność algorytmów

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

Zadanie projektowe 1: Struktury danych i złożoność obliczeniowa

Sortowanie. LABORKA Piotr Ciskowski

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Wprowadzenie do złożoności obliczeniowej

Zaawansowane algorytmy i struktury danych

Algorytmy sortujące 1

Temat 7. Najlżejsze i najcięższe algorytmy sortowania

Algorytmy i Struktury Danych.

Porównanie czasów działania algorytmów sortowania przez wstawianie i scalanie

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy i struktury danych

PODSTAWY INFORMATYKI wykład 5.

Algorytm selekcji Hoare a. Łukasz Miemus

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

Metodyki i Techniki Programowania 2

Porównanie Heap Sort, Counting Sort, Shell Sort, Bubble Sort. Porównanie sortowao: HS, CS, Shs, BS

Programowanie Proceduralne

Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze,

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

Efektywna metoda sortowania sortowanie przez scalanie

Przykładowe sprawozdanie. Jan Pustelnik

Wstęp do programowania

Wrocław, Wstęp do informatyki i programowania: liczby pierwsze. Wydział Matematyki Politechniki Wrocławskiej.

Złożoność algorytmów. Wstęp do Informatyki

Analiza algorytmów zadania podstawowe

Sortowanie przez wstawianie Insertion Sort

Jeszcze o algorytmach

Wykład 4. Sortowanie

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

Podstawy Programowania 1 Sortowanie tablic jednowymiarowych. Plan. Sortowanie. Sortowanie Rodzaje sortowania. Notatki. Notatki. Notatki.

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

Algorytmy i Struktury Danych

Podstawowe struktury danych

Teoretyczne podstawy informatyki

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Złożoność Obliczeniowa Algorytmów

Laboratoria nr 1. Sortowanie

Algorytmy i struktury danych Sortowanie IS/IO, WIMiIP

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy i Struktury Danych.

Wstęp do programowania

Wstęp do programowania

Technologie informacyjne Wykład VII-IX

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

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

Algorytmy i Struktury Danych. (c) Marcin Sydow. Introduction. QuickSort. Sortowanie 2. Limit. CountSort. RadixSort. Summary

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

. Podstawy Programowania 1. Sortowanie tablic jednowymiarowych. Arkadiusz Chrobot. 16 listopada 2016

Algorytmy i Struktury Danych, 2. ćwiczenia

Problemy porządkowe zadania

Złożoność obliczeniowa zadania, zestaw 2

Informatyka 1. Złożoność obliczeniowa

Teoretyczne podstawy informatyki

Sortowanie zewnętrzne

Sortowanie bąbelkowe - wersja nr 1 Bubble Sort

Źródła. N.Wirth Algorithms and Data Structures, 1985 D.E.Knuth The Art of Computer Programming. Vol. 3, 1973

Technologie cyfrowe. Artur Kalinowski. Zakład Cząstek i Oddziaływań Fundamentalnych Pasteura 5, pokój 4.15

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

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

PODSTAWY INFORMATYKI wykład 10.

Wieczorowe Studia Licencjackie Wrocław, Wykład nr 6 (w oparciu o notatki K. Lorysia, z modyfikacjami) Sito Eratostenesa

Algorytmy i struktury danych Matematyka III sem.

Struktury danych i złożoność obliczeniowa Wykład 2. Prof. dr hab. inż. Jan Magott

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

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

Algorytmy i struktury danych

1. Analiza algorytmów przypomnienie

Transkrypt:

Podstawy programowania Przykłady algorytmów Cz. 2 Sortowanie

Złożoność obliczeniowa Złożoność obliczeniowa to ilość zasobów niezbędna do wykonania algorytmu. Wyróżnia się dwa rodzaje: Złożoność czasową (obliczeniową) Złożoność pamięciową Złożoność zależy od rozmiaru danych wejściowych (np. sortowanie, niezależnie od użytego algorytmu, będzie trwało tym dłużej, im większy jest zbiór sortowanych elementów)

Złożoność obliczeniowa Istnieje wiele miar złożoności obliczeniowej i wiele notacji. W większości miar najważniejsze jest asymptotyczne tempo wzrostu (tj. jak złożoność rośnie ze wzrostem rozmiaru danych). Do porównywania algorytmów najczęściej używa się notacji O (dużego O), która podaje asymptotyczne ograniczenie górne W notacji O uwzględnia się tylko funkcję dominującą i pomija się współczynniki liczbowe, ponieważ dla odpowiednio dużych zbiorów danych współczynniki stałe mają mniej istotne znaczenie niż rodzaj funkcji dominującej, np. f(n) = 100 n 2 + 50 n => O(n 2 ) f(n) = 1000 n => O(n)

Złożoność obliczeniowa Przykładowe złożoności algorytmów, w porządku rosnącym: O(1) złożoność stała, O(logn) złożoność logarytmiczna, O(n) złożoność liniowa, O(nlogn) złożoność liniowo-logarytmiczna, O(n 2 ) złożoność kwadratowa, O(n k ) złożoność wielomianowa (k jest stałą), O(k n ) złożoność wykładnicza (k jest stałą), O(n!) złożoność rzędu silnia

Złożoność obliczeniona 1,0E+12 1,0E+11 1,0E+10 1000 lat 100 lat 1,0E+09 1,0E+08 1 rok 1,0E+07 1,0E+06 1,0E+05 1,0E+04 1,0E+03 1,0E+02 1,0E+01 1,0E+00 1 doba 1 godz. 1 min. 1 s 1,0E-01 1,0E-02 1,0E-03 1 ms 1,0E-04 1,0E-05 1,0E-06 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 1E+10 N N*logN N^2 2^N N!

Sortowanie Sortowanie Istnieje wiele algorytmów sortowania; niektóre mają bardzo specyficzne lub ograniczone zastosowanie (np. stosowane głównie w systemach wbudowanych albo kiedy możliwość ich użycia zależy od statystycznych cech sortowanego zbioru), inne są uniwersalne. Pierwsze algorytmy sortowania pojawiły się w latach 50 ub. wieku (m.in. bublesort 1956, quicksort 1959), ale ciągle są opracowywane nowe użyteczne algorytmy, które znajdują zastosowania (np. timsort, opracowany w 2002 r., jako hybrydowy algorytm merge sort oraz insertion sort, zastosowany m.in. jako wbudowany algorytm sortowania w językach Python i GNU Octave, oraz na platformach Java SE i Android) Duże zainteresowanie algorytmami sortowania wynika z powszechności zastosowań, dużej złożoności obliczeniowej (oraz potrzeby jej zmniejszenia, ze względu na powszechne i częste zastosowania) Algorytmy sortowania są też wdzięcznym tematem nauki programowania (algorytmy jako takie, ale też np. złożoność obl.)

Sortowanie Właściwości i kryteria oceny algorytmów sortowania: Złożoność obliczeniowa Nie zawsze można ją określić jednoznacznie, ponieważ w wielu algorytmach zależy od rozkładu elementów dlatego wyznacza się złożoność optymistyczną (best), średnią i pesymistyczną (worst); Złożoność pamięciowa Algorytmy sortowania "w miejscu" ("in-place") zamieniają elementy miejscami i nie potrzebują dodatkowej pamięci na same elementy, jednak czasami zużywają inne zasoby; Rekursja Użycie rekursji zużywa zasoby (stos systemowy), co może ograniczać zastosowania algorytmów np. quicksort i syst. wbudowane; Istnieją algorytmy rekusywne, nierekursywne oraz mieszane

Sortowanie Właściwości i kryteria oceny algorytmów sortowania: Stabilność Algorytm sortowania jest stabilny, jeżeli "równe" elementy po sortowaniu zachowują swój porządek sprzed sortowania; Mechanizm sortowania (sposób działania) Wyróżnia się algorytmy sortowania przez porównanie ("comparison sort") oraz takie, które porównania nie używają ("integer sort"); Metoda sortowania Wyróżnia się kilka ogólnych metod: sortowanie przez wstawianie, zamiany, wybór, łączenie konkretne algorytmy należą do jednej z metod ogólnych, np. bublesort jest sortowaniem przez zamiany

Sortowanie Właściwości i kryteria oceny algorytmów sortowania: Adaptacyjność Zdolność do skrócenia czasu sortowania, jeżeli zbiór jest częściowo posortowany (ma część elementów we właściwej kolejności) np. bublesort ma śrenią złożoność O(n 2 ) oraz optymistyczną O(n), natomiast insertion sort zawsze O(n 2 ) Złożoność implementacji Niektóre hybrydowe algorytmy sortowania mają bardzo złożone algorytmy, a ich implementacja może być kłopotliwa dla początkującego programisty; inne, jak bublesort, są dziecinnie proste

Sortowanie Algorytmy sortowania stabilne: sortowanie bąbelkowe (ang. bubblesort) O(n 2 ) sortowanie przez wstawianie (ang. insertion sort) O(n 2 ) sortowanie przez scalanie (ang. merge sort) O(nlogn) wymaga dodatkowej pamięci O(n) sortowanie przez zliczanie (ang. counting sort) O(n+k) wymaga dodatkowej pamięci sortowanie kubełkowe (ang. bucket sort) O(n) wymaga dodatkowej pamięci sortowanie biblioteczne (ang. library sort) O(nlogn)

Sortowanie Algorytmy sortowania niestabilne : sortowanie przez wybieranie (ang. selection sort) O(n 2 ) sortowanie Shella (ang. shellsort) O(nlogn) sortowanie szybkie (ang. quicksort) O(nlogn) sortowanie przez kopcowanie (ang. heapsort) O(nlogn)

Sortowanie Złożoność obliczeniowa Sortowanie przez porównanie Na sortowanie przez porównanie składają się dwie operacje: porównywania elementów i (ewentualnie) ich zamiany która z tych operacji jest bardziej krytyczna? Przy sortowaniu liczb więcej czasu zajmie zamiana (wykonywana w trzech krokach: temp t i, t i t j, t j temp) Przy sortowaniu złożonych danych wielokrotnie więcej czasu zajmie porównanie (np. "Kowalski, Bartłomiej" i "Kowalski, Bartosz"); zamiana zwykle nie dotyczy samych danych to strata czasu tylko referencji do nich Uwaga! W dalszej części zamiana liczb, dla skrócenia zapisu, będzie oznaczana tak: t i t i+1 odpowiada to trzykrokowej operacji powyżej

Sortowanie Złożoność obliczeniowa Sortowanie przez porównanie Najprostsze ("naturalne", intuicyjnie zrozumiałe) algorytmy sortowania mają złożoność obliczeniową O(n 2 ) średnią lub pesymistyczną Dolne ograniczenie złożoności wynosi O(nlogn) istnieją zarówno stabilne, jak i niestabilne algorytmy o tej złożoności Sortowanie bez porównań ("integer sort") Najprostsze algorytmy mają złożoność O(n k) lub O(n+r) (k oznacza rozmiar klucza sortowania, r zakres wartości kluczy) Dolne ograniczenie złożoności wynosi O(n), jednak jest osiągalne tylko dla algorytmów niestabilnych Sortowanie bez porównań ma istotne praktyczne ograniczenia (co do złożoności klucza sortowania oraz rozkładu wartości kluczy) oraz zwykle większą złożoność pamięciową, co najmniej O(n)

Sortowanie bąbelkowe Sortowanie bąbelkowe jest chyba najprostszym pojęciowo oraz najłatwiejszym w implementacji algorytmem sortowania Polega na porównywaniu sąsiednich elementów i w razie potrzeby ich zamianie; Przy N elementach trzeba N-1 porównań, a cały proces trzeba powtórzyć co najwyżej N-1 razy FOR n=0, 1,, N-2 FOR i=0, 1,, N-2 IF t i > t i+1 t i t i+1

Sortowanie bąbelkowe Udoskonalenia (1) Algorytm można zakończyć, jeżeli wewnętrzna pętla nie wykona ani jednej zamiany (wtedy zewnętrzna pętla może być nieskończona) FOR Z = false FOR i=0, 1,, N-2 IF t i > t i+1 t i t i+1 Z = true IF NOT(Z) BREAK

Sortowanie bąbelkowe Udoskonalenia (2) Po pierwszym wykonaniu pętli wewnętrznej element największy znajdzie się na samym końcu ("wygra" wszystkie porównania) liczba porównań pętli wewnętrznej może być zmniejszana Można połączyć z (1) FOR n=0, 1,, N-2 FOR i=0, 1,, N-n-2 IF t i > t i+1 t i t i+1 FOR n=n-2, N-1,, 2 FOR i=0, 1,, n IF t i > t i+1 t i t i+1

Sortowanie bąbelkowe Udoskonalenia (3) Jeżeli zbiór będzie prawie posortowany, z wyjątkiem ostatniego elementu (np. { 2, 3, 4, 5, 6, 1 }), to algorytm będzie miał złożoność O(n 2 ), chociaż mógłby mieć O(n) gdyby odwrócić kierunek sortowania aby takiemu efektowi zapobiec, wewnętrzna pętla powinna na zmianę biec w górę i w dół zbioru, po coraz krótszym jego fragmencie FOR l = 1 r = N-2 FOR i = l, l+1,, r IF t i > t i+1 => t i t i+1 r r-1 FOR i = r, r-1,, l IF t i > t i+1 => t i t i+1 l l+1

Sortowanie gnoma Ciekawy wariant sortowania bąbelkowego, przedstawiany w formie dykteryjki: gnom (niezbyt inteligentny) ma w ogrodzie poukładać doniczki z kwiatami wg wysokości kwiatów; zaczyna od jednej strony (np. od lewej) i porównuje kwiat, przy którym stoi z następnym. Jeżeli są we właściwej kolejności, to przechodzi dalej, jeżeli nie, to zamienia je miejscami i cofa się (chyba że już jest na samym początku) 3 4 5 1 6 2

Sortowanie gnoma Ulepszenie Wadą algorytmu jest jałowe powtarzanie porównań podczas poruszania się w prawo, zaraz po cofnięciu się w lewo: 3 4 5 1 2 6

Sortowanie gnoma Ulepszenie Wadą algorytmu jest jałowe powtarzanie porównań podczas poruszania się w prawo, po cofnięciu się w lewo Wiadomo, że od bieżącego miejsca aż do miejsca, gdzie dotarł poprzednio, kwiaty są posortowane => powinien to miejsce zaznaczyć (powiesić tam swoją czapkę?) i od razu tam wrócić 1 3 4 5 2 6

Sortowanie gnoma Wersja bez ulepszenia p = 0 WHILE p<n-1 IF t p > t p+1 t p t p+1 IF p>0 p p-1 ELSE p p+1 3 4 5 1 6 2

Sortowanie przez wstawianie Przypomina układanie kart w ręku gracza: dzielimy elementy zbioru na część posortowaną (z lewej) i nieposortowaną (z prawej); należy pobrać pierwszy element z części nieposortowanej i przesuwając się w lewo znaleźć miejsce, gdzie powinien się znaleźć. Elementy posortowane, od tego miejsca aż do części nieposortowanej, należy przesunąć w prawo, żeby zrobić miejsce dla elementu wstawianego FOR n = 1, 2,, N-1 temp = t n i = n 1 WHILE i>=0 AND t i >temp t i+1 t i i i-1 t i+1 = temp

Sortowanie przez wybieranie Koncepcyjnie zbliżony do sortowania przez wstawianie, ale niestabilny. Najprostsza wersja polega na szukaniu minimum dla nieposortowanej przez kolejne porównania i (ewentualnie) zamiany elementu z początku tej części ze wszystkimi kolejnymi elementami: FOR n = 0, 1,, N-2 FOR i = n+1, n+2, N-1 IF t i <t n t i t n metoda jest niewydajna, ponieważ elementy w nieposortowanej części mają tendencję do układania się w porządku malejącym

Sortowanie przez wybieranie Najlepszy wariant sortowania przez wybieranie polega na szukaniu minimum w nieposortowanej (prawej) części zbioru i jednorazowej zamianie miejscami minimum oraz pierwszego elementu tej części: FOR n = 0, 1,, N-2 min = t n poz = n FOR i = n+1, n+2, N-1 IF t i < min min t i poz = i t n t poz

Sortowanie złożoność obliczeniowa Wszystkie proste algorytmy mają złożoność średnią O(n 2 ). Np. dla sortowania przez wybieranie, dla N elementów jest (N/2)(N-1) porównań: E E E E E P P P P P P P P P N-1 P N-1

Sortowanie medianowe Koncepcja z pozoru słuszna, w praktyce zupełnie nieprzydatna, leżąca u podstaw innych wydajnych algorytmów, a w tym bardzo popularnych (np. quicksort), o złożoności O(nlogn)

Sortowanie medianowe Skoro proste sortowanie ma złożoność O(n 2 ) to może zróbmy tak: podzielmy zbiór na dwie połowy i posortujmy je oddzielnie czas powinien być 2 x mniejszy: 2 x (n/2) 2 = ½ n 2 Skoro tak, to czemu tego nie powtórzyć dzieląc połowy tablicy znów na połowy, znowu zyskamy na czasie: 4 x (n/4) 2 = ¼ n 2 Gdyby powtórzyć to parę razy (aż do fragmentu tablicy o rozmiarze 1), to takich kroków będzie log 2 n, a złożoność obliczeniowa n logn

Sortowanie medianowe Tak może wyglądać pierwszy etap sortowania: 2 14 7 15 3 19 5 11 2 14 7 15 3 19 5 11 2 7 14 15 3 5 11 19 Niestety powstaje pewien drobny problem posortowane oddzielnie tablice po połączeniu wcale nie tworzą tablicy posortowanej

Sortowanie medianowe Tak może wyglądać pierwszy etap sortowania: 2 14 7 15 3 19 5 11 2 14 7 15 3 19 5 11 2 7 14 15 3 5 11 19 Niestety powstaje pewien drobny problem posortowane oddzielnie tablice po połączeniu wcale nie tworzą tablicy posortowanej Rozwiązanie: załóżmy, że M jest medianą tablicy (tj. dokładnie połowa elementów jest od M mniejsza, a połowa większa) trzeba przerzucić te mniejsze na lewo, a większe na prawo, a dopiero potem sortować

Sortowanie medianowe Sortowanie medianowe (pierwszy etap): 2 14 7 15 3 19 5 11 2 14 7 15 3 19 5 11 2 5 7 3 15 19 14 11 Wygląda na to, że błąd został poprawiony. Skoro tak, to czynności można powtórzyć, dzieląc tablice znowu na połowy

Sortowanie medianowe Sortowanie medianowe (całość): 2 14 7 15 3 19 5 11 2 14 7 15 3 19 5 11 2 5 7 3 15 19 14 11 2 5 7 3 15 19 14 11 2 3 7 5 11 14 19 15 2 3 7 5 11 14 19 15 2 3 5 7 11 14 15 19

Sortowanie medianowe Sortowanie medianowe (całość): 2 14 7 15 3 19 5 11 2 5 7 3 15 19 14 11 2 3 7 5 11 14 19 15 2 3 5 7 11 14 15 19 W sortowaniu medianowym sortowanie polega wyłącznie na przerzucaniu elementów pomiędzy połówkami zbioru nie porównuje się elementów z innymi elementami, a wyłącznie z medianą, złożoność obliczeniowa jest najlepsza możliwa, O(nlogn), jest jednak pewien problem

Sortowanie medianowe Sortowanie medianowe (całość): 2 14 7 15 3 19 5 11 2 5 7 3 15 19 14 11 2 3 7 5 11 14 19 15 2 3 5 7 11 14 15 19 W sortowaniu medianowym sortowanie polega wyłącznie na przerzucaniu elementów pomiędzy połówkami zbioru nie porównuje się elementów z innymi elementami, a wyłącznie z medianą, złożoność obliczeniowa jest najlepsza możliwa, O(nlogn), jest jednak pewien problem złożoność szukania mediany jest O(n 2 )

Sortowanie medianowe Sortowanie medianowe, przez złożoność szukania mediany O(n 2 ), jest nieopłacalne, jednak sama koncepcja podziału zbioru na połowy leży u podstaw dwóch wydajnych algorytmów sortowania (i pewnej liczby ich odmian i wariacji): Sortowanie przez scalanie (merge sort) "posortujmy te połówki oddzielnie, potem coś wykombinujemy" Szybkie sortowanie (quicksort) "weźmy coś prostszego zamiast tej całej mediany, potem zobaczymy co wyszło"

Sortowanie złożoność obliczeniowa Algorytmy bazujące na medianowym mają złożoność średnią O(nlogn). Np. dla sortowania medianowego jest N log 2 N porównań: E E E E E P P P P P P P P log 2 N N-1 Dla sortowania medianowego, sortowania przez scalanie i szybkiego jest log 2 N podziałów zbioru na połowy. Oznacza to log 2 N scaleń (każde N porównań) w merge sort, podobnie log 2 N poziomów rekurencji i przerzucania (małe na lewo duże na prawo, N porównań) w quicksort

Sortowanie przez scalanie Sortowanie przez scalanie (merge sort) polega na oddzielnym sortowaniu (hipotetycznie) połówek zbioru, a następnie ich scaleniu, prze wybieranie z lewej i prawej części kolejnych najmniejszych elementów; pomysł jest powielany na kolejnych poziomach podziału zbioru na połowy 2 14 7 15 3 19 5 11 2 14 7 15 3 19 5 11 2 7 14 15 3 5 11 19 2 3

Szybkie sortowanie Szybkie sortowanie (quicksort) jest najbliższe sortowaniu medianowemu, tyle że zamiast mediany jest brana wartość ją zastępująca zależnie od implementacji: wartość z arytmetycznego środka zbioru (najczęściej) wartość z losowo wybranej pozycji średnia arytmetyczna z kilku pozycji Optymistyczna złożoność obliczeniowa O(nlogn), pesymistyczna O(n 2 ) (bardzo mało prawdopodobna) Zaimplementowana starannie pod kątem wydajności jest 2-3 x szybsza niż merge sort i heap sort; Jest wykonywany "w miejscu", jednak rekurencyjnie - zużywa stos, co w komputerach o małych zasobach jest kłopotliwe Jest niestabilny (istnieją też warianty stabilne)

Szybkie sortowanie Szybkie sortowanie (quicksort) implementacja Implementacja pozornie jest prosta: QUICSORT (t, p, k) s = PodzielTablice(t, p, k) QUICKSORT(t, p, s) QUICKSORT(t, s+1, k) W praktyce podział (z przerzuceniem elementów mniejszych od "pseudo-mediany" na prawo i mniejszych od niej na lewo) jest kłopotliwy, ponieważ części tablicy nie muszą być równe (zależą od wartości "pseudo-mediany") Istnieją implementacje wykorzystujące 3 pętle while, dość trudne: WHILE (pp <> kk) WHILE (pp<kk AND t pp <quasimed) pp++ WHILE (kk>pp AND t kk >quasimed) kk t pp t kk

Szybkie sortowanie Szybkie sortowanie (quicksort) implementacja Najprostsza implementacja używa jednej pętli for i sprytnej sztuczki: ustawia "pseudomedianę" pomiędzy lewą i prawą częścią tablicy, dzięki czemu dalsze sortowanie tego elementu już nie dotyczy: QUICSORT (t, p, k) IF (p >= k) return; pivotpoint = p + (k-p)/2 pivotvalue = t[pivotpoint] t[pivotpoint] t[k] splitpoint = p FOR i=p, p+1,, k-1 IF t[i]<pivotvalue t[i] t[splitpoint] splitpoint++ t[splipoint] t[k] // koniec rekurencji // środek tablicy // pseudomediana // "środek" na koniec // punkt podziału tabl. // bez "środka"!!! // "środek" na środek QUICSORT (t, p, splitpoint-1) // rekurencja QUICSORT (t, splitpoint+1, k)

Sortowanie bez porównywania Sortowanie bez porównywania ma ograniczone zastosowania dla zbiorów o równomiernym rozkładzie kluczy, należących do skończonego zbioru, najlepiej o kluczach całkowitych, przy niewielkiej liczbie kluczy "pustych" wówczas osiąga złożoność O(n) Wadą tych algorytmów jest złożoność pamięciowa przynajmniej O(n)

Sortowanie przez zliczanie Sortowanie przez zliczanie (counting sort) Może być stosowana dla zbiorów o równomiernym rozkładzie kluczy należących do skończonego zbioru wówczas osiąga złożoność O(n+k) oraz złożoność pamięciową O(n+k), gdzie n oznacza liczebność zbioru, k rozpiętość wartości kluczy Polega na utworzeniu histogramu, tj. policzeniu liczby wystąpień kluczy o tej samej wartości. Później wartości są wkładane wprost na pozycję wynikającą z histogramu Jest stabilny W skrajnym przypadku (kiedy klucze nie powtarzają się) ma złożoność obliczeniową O(n) i pamięciową O(k) Nie nadaje się do sortowania złożonych danych (np. dane osobowe, alfabetycznie) co prawda klucze da się wyznaczyć, ale rozpiętość jest zbyt duża i złożoność pamięciowa jest nie do przyjęcia

Sortowanie kubełkowe Sortowanie kubełkowe (bucket sort) Wariant koncepcji poprzedniej należy podzielić zakres rozpiętości kluczy na k przedziałów (kubełków), następnie przeglądając elementy zbioru przypisywać je do odpowiedniego kubełka na podstawie wartości klucza (złożoność O(n)). Niepuste kubełki trzeba posortować (stosując mniejsze kubełki) itd. Przy równomiernym rozkładzie kluczy całkowitych osiąga złożoność O(n+k) oraz złożoność pamięciową O(n+k) i jest stabilny

Bogosort Pseudosortowanie (bogus sort) Jeden z algorytmów zaprojektowanych tak, aby były jak najwolniejsze. Polega na losowym ustawianiu elementów zbioru przy każdej iteracji i sprawdzaniu, czy przypadkiem kolejność nie jest właściwa (niemalejąca). Możliwych permutacji zbioru n elementów jest n!, stąd złożoność obliczeniowa O(n!) Już przy kilkudziesięciu elementach czas sortowania trzeba liczyć w miliardach lat (np. 25! 1,5 10 25, 50! 3 10 64 ) FOR gotowe = true FOR i=0, 1,, N-1 IF t i >t i+1 gotowe = false; BREAK IF gotowe BREEAK FOR i=n-1, N-2,, 1 t i t random(i)