Algoritmy vyhledávání a řazení. Zatím nad lineární datovou strukturou (polem)

Podobné dokumenty
Časová složitost algoritmů

Algoritmy I, složitost

Časová složitost algoritmů, řazení a vyhledávání

Základy algoritmizace a programování

Algoritmizace prostorových úloh

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

Algoritmizace řazení Bubble Sort

IB111 Úvod do programování skrze Python

A4B33ALG 2010/05 ALG 07. Selection sort (Select sort) Insertion sort (Insert sort) Bubble sort deprecated. Quicksort.

V případě jazyka Java bychom abstraktní datový typ Time reprezentující čas mohli definovat pomocí třídy takto:

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

Obsah přednášky. Analýza algoritmu Algoritmická složitost Návrhy algoritmů Urychlování algoritmů 1/41

Časová složitost / Time complexity

10. Složitost a výkon

ALGORITMY A DATOVÉ STRUKTURY

Adresní vyhledávání (přímý přístup, zřetězené a otevřené rozptylování, rozptylovací funkce)

Digitální učební materiál

Pole a kolekce. v C#, Javě a C++

DobSort. Úvod do programování. DobSort Implementace 1/3. DobSort Implementace 2/3. DobSort - Příklad. DobSort Implementace 3/3

Prohledávání do šířky = algoritmus vlny

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

IB111 Úvod do programování skrze Python

Časová a prostorová složitost algoritmů

Složitost. Teoretická informatika Tomáš Foltýnek

Datové struktury 2: Rozptylovací tabulky

Michal Krátký. Úvod do programování. Cíl kurzu. Podmínky získání zápočtu III/III

Složitost 1.1 Opera ní a pam ová složitost 1.2 Opera ní složitost v pr rném, nejhorším a nejlepším p ípad 1.3 Asymptotická složitost

Základy řazení. Karel Richta a kol.

NP-ÚPLNÉ PROBLÉMY. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

NPRG030 Programování I, 2018/19 1 / :03:07

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Zdůvodněte, proč funkce n lg(n) roste alespoň stejně rychle nebo rychleji než než funkce lg(n!). Symbolem lg značíme logaritmus o základu 2.

Tato tematika je zpracována v Záznamy přednášek: str

Dynamické datové struktury III.

ÚVODNÍ ZNALOSTI. datové struktury. správnost programů. analýza algoritmů

Algoritmizace. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Složitost algoritmů. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

Dynamické programování

Složitost algoritmů. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

přirozený algoritmus seřadí prvky 1,3,2,8,9,7 a prvky 4,5,6 nechává Metody řazení se dělí:

Různé algoritmy mají různou složitost

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Digitální učební materiál

Maturitní téma: Programovací jazyk JAVA

11 VYPOČITATELNOST A VÝPOČTOVÁ SLOŽITOST

Algoritmy a datové struktury

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Prioritní fronta, halda

Databáze, sítě a techniky programování X33DSP

Algoritmizace a programování

Třídící algoritmy. Insert Sort. Bubble Sort. Select Sort. Shell Sort. Quick Sort. Merge Sort. Heap Sort.

Řešení: PŘENESVĚŽ (N, A, B, C) = přenes N disků z A na B pomocí C

3 Algoritmy řazení. prvku a 1 je rovněž seřazená.

Sada 1 - Základy programování

Amortizovaná složitost. Prioritní fronty, haldy (binární, d- regulární, binomiální, Fibonacciho), operace nad nimi a jejich složitost

5. Vyhledávání a řazení 1

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Hledání k-tého nejmenšího prvku

Algoritmy výpočetní geometrie

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

Složitost UPR 2008/09 1

Třídy složitosti P a NP, NP-úplnost

Mimo samotné správnosti výsledku vypočteného zapsaným algoritmem je ještě jedno

Úvod do informatiky. Miroslav Kolařík

COMPLEXITY

Rekurzivní algoritmy

NPRG030 Programování I 3/2 Z --- NPRG031 Programování II --- 2/2 Z, Zk

5 Rekurze a zásobník. Rekurzivní volání metody

Základní datové struktury III: Stromy, haldy

ˇ razen ı rychlejˇ s ı neˇ z kvadratick e Karel Hor ak, Petr Ryˇsav y 20. dubna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

Doba běhu daného algoritmu/programu. 1. Který fragment programu z následujících dvou proběhne rychleji?

Třídění a vyhledávání Searching and sorting

13. Třídící algoritmy a násobení matic

Pokročilé řazení. Karel Richta a kol. Přednášky byly připraveny s pomocí materiálů, které vyrobili Marko Berezovský a Michal Píše

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

a) b) c) Radek Mařík

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Základní informace o předmětu Otázka:

Stromy, haldy, prioritní fronty

Binární vyhledávací strom pomocí směrníků Miroslav Hostaša L06620

Algoritmy a datové struktury

Úvod do problematiky

Programování v C++, 2. cvičení

2. Složitost, grafové algoritmy (zapsal Martin Koutecký)

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Bubble sort. příklad. Shaker sort

Základy programování (IZP)

Slepé prohledávání do šířky Algoritmus prohledávání do šířky Při tomto způsobu prohledávání máme jistotu, že vždy nalezneme koncový stav, musíme ale p

Vztah teorie vyčíslitelnosti a teorie složitosti. IB102 Automaty, gramatiky a složitost, /31

NMIN101 Programování 1 2/2 Z --- NMIN102 Programování /2 Z, Zk

Vyvažování a rotace v BVS, všude se předpokládá AVL strom

ALG 09. Radix sort (přihrádkové řazení) Counting sort. Přehled asymptotických rychlostí jednotlivých řazení. Ilustrační experiment řazení

Digitální učební materiál

Složitosti základních operací B + stromu

Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, Základní algoritmy v praxi

Pokročilé haldy. prof. Ing. Pavel Tvrdík CSc. Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010

4. Rekurze. BI-EP1 Efektivní programování Martin Kačer

Úvod do programování 10. hodina

Transkript:

Algoritmy vyhledávání a řazení Zatím nad lineární datovou strukturou (polem)

Vyhledávací problém Vyhledávání je dáno Universum (množina prvků) U je dána konečná množina prvků X U (vyhledávací prostor) mějme prvek x U vyhledávací problém (Najdi(x,X)) je definován jako rozhodovací problém: Najdi(x,X): jestliže x X, pak najdi=1, jinak najdi=0

algoritmy vyhledávání závisejí na vyhledávacím prostoru a jeho reprezentaci druhy vyhledávacích problémů: dynamický lexikon vyhledávací prostor se v průběhu zpracování mění (vložení, rušení, náhrada prvku) příklad: autorský katalog knihovny statický lexikon vyhledávací prostor se v průběhu zpracování nemění příklad: telefonní seznam

pro jednoduchost se omezíme na čísla typu int (univerzum U = int) množina X, ve které provádíme hledání, bude reprezentována polem čísel (zatím, poznáme i jiné výhodnější reprezentace, např. strom) jako výsledek hledání při programování zpravidla potřebujeme znát index nalezeného prvku (resp. ukazatel)

Sekvenční vyhledávání používá se při vyhledávání v poli (seznamu), které je neseřazené princip: sekvenčně (v cyklu) procházím prvky pole, dokud prvek nenaleznu nebo neprojdu celé pole

budeme předpokládat následující pole #define MAX 100 int pole[max]; implementujeme vyhledávací funkci, která zjistí, zda je v poli, obsahující n prvků, hledaný prvek x; v kladném případě vrátí funkce index prvku, v případě neúspěchu hodnotu -1

int hledej(int x, int *pole, int n) /* x je hledaný prvek, n je počet prvků pole */ { } int i=0; while(i<n && pole[i]!=x) i++; return i!=n? i : -1;

někdy se implementovalo sekvenční vyhledávání se zarážkou (tzv. sentinel) pole má o jeden prvek navíc (poslední), do kterého vložím hledaný prvek došlo ke zjednodušení podmínky v cyklu

int hledej2(int x, int *pole, int n) { int i=0; pole[n]=x; while(pole[i]!=x) i++; return i!=n? i: -1; }

Vyhledávání binárním půlením používá se při vyhledávání v poli, kde jsou prvky seřazeny princip: porovnám hledaný prvek x s prvkem uprostřed pole pole[i] dojde-li ke shodě, prvek je nalezen; je-li x<pole[i], pokračuji v hledání v levé polovině pole bin. půlením, je-li x>pole[i], pokračuji v hledání v pravé polovině pole bin. půlením vyhledávání končí neúspěchem, je-li prohledávaná část pole prázdná

int bin_pul(int x, int *pole, int n) { int i,l,p; l=0; p=n-1; do { i = (l+p)/2; if (x<pole[i]) p=i-1; else l=i+1; } while(pole[i]!=x && l<=p); return pole[i]==x? i: -1; }

trochu jinak: int bin_pul(int x, int *pole, int n) { } int i,l,p; l=0; p=n-1; do { } i = (l+p)/2; if (x==pole[i]) return i; if (x<pole[i]) p=i-1; else l=i+1; while(l<=p); return -1;

binární půlení se někdy vylepšuje jiným výpočtem indexu i (lineární interpolace podle hodnoty hledaného prvku vzhledem k nejmenšímu a největšímu prvku v poli) i = (p-l)*(x-pole[l])/(pole[p]-pole[l])

Hodnocení algoritmů rychlost (kvalitu) algoritmů měříme tzv. složitostí (complexity) : operační složitostí O(n) doba trvání (počet kroků) algoritmu v závislosti na rozměru problému, např. na počtu řazených čísel, velikost prohledávacího prostoru paměťovou složitostí M(n) velikost požadované paměti v závislosti na rozměru problému

Hodnocení algoritmů rychlost běhu programu závisí na mnoha faktorech rychlost procesoru, velikost cache, progr. jazyku, překladači, stylu programování, snažíme se určit rychlost algoritmu bez ohledu na tyto faktory; zajímá nás většinou chování algoritmu pro velké množství vstupních dat

Hodnocení algoritmů rychlost (kvalitu) algoritmů měříme tzv. asymptotickou složitostí (complexity) jak závisí počet kroků algoritmu na počtu vstupních dat n limitně pro n snažíme se eliminovat konstanty složitosti vyjadřujeme tzv. řádem růstu funkce

Hodnocení algoritmů Asymptotická horní mez: O-notace jsou-li dány funkce f(n) a g(n), pak řekneme, že f(n) je nejvýše řádu g(n), f(n) = O(g(n)), jestliže platí c R + + n N : 0 n n 0 : f(n) c.g(n) říkáme také, že f(n) roste maximálně tak rychle jako g(n) používáme ji pro vyjádření horní meze růstu až na multiplikativní konstantu

Hodnocení algoritmů Asymptotická dolní mez: Ω-notace jsou-li dány funkce f(n) a g(n), pak řekneme, že f(n) je nejméněřádu g(n), f(n) = Ω(g(n)), jestliže platí c R + + n N : 0 n n 0 : f(n) c.g(n) říkáme také, že f(n) roste minimálně tak rychle jako g(n) používáme ji pro vyjádření dolní meze růstu až na multiplikativní konstantu

Hodnocení algoritmů Asymptotická těsná mez: Θ-notace jsou-li dány funkce f(n) a g(n), pak řekneme, že f(n) je téhož řádu jako g(n), f(n) = Θ(g(n)), jestliže platí + + c1, c2 R n0 N : n n0 :c1g ( n) f(n) c2g(n) říkáme také, že f(n) roste stejně tak rychle jako g(n) až na multiplikativní konstantu

Hodnocení algoritmů platí f(n) = Θ(g(n)) f(n) = O(g(n)) f(n) = Ω(g(n))

např. 3n 2 + 2n + 5 je řádu O(n 2 ) 5n 4 + 3n 2-3 je řádu O(n 4 ) 2 n + 3 je řádu O(2 n ) n! + 3n + 4 je řádu O(n!) polynomiální exponenciální faktoriální

Odhadněte operační složitost: sekvenčního vyhledávání O(n) násobení čtvercových matic o rozměru n O(n 3 ) hledání binárním půlením O(log 2 n)

někdy se stanovuje složitost pro různé případy uspořádání vstupních dat: v nejlepším případě v průměrném případě často je složité statisticky určit tento případ v nejhorším případě příklad: lineární hledání: hledaný prvek je na prvním místě v poli hledaný prvek je uprostřed hledaný prvek je na konci pole nebo není přítomen

Řazení Řazení: vytvoření posloupnosti prvků x i, takové, že x j1 x j2,, x jn resp. x j1 x j2,, x jn univerzální algoritmy řazení: zatřiďováním výběrem maximálního (minimálního) prvku záměnou (Bubble Sort) Quick Sort

Řazení zatřiďováním do již seřazené posloupnosti vkládáme každý nový prvek rovnou na správné místo vhodné např. pro spojový seznam, nikoliv pro pole nutné spojit s operací hledání

Řazení výběrem maximálního (minimálního) prvku v poli o n prvcích nalezneme maximální (minimální) prvek a vyměníme jej s posledním (prvním) prvkem krok hledání maximálního (minimálního) prvku opakujeme na poli o délce n-1, n- 2,,1

0 1 2 3 4 6 7 3 2 5 imax: 0 max: 6

0 1 2 3 4 6 7 3 2 5 imax: 0 max: 6

0 1 2 3 4 6 7 3 2 5 imax: 1 max: 7

0 1 2 3 4 6 7 3 2 5 imax: 1 max: 7

0 1 2 3 4 6 7 3 2 5 imax: 1 max: 7

0 1 2 3 4 6 7 3 2 5 imax: 1 max: 7

0 1 2 3 4 6 5 3 2 7 imax: 1 max: 7

0 1 2 3 4 6 5 3 2 7 imax: 1 max: 7

0 1 2 3 4 6 5 3 2 7 imax: 0 max: 6

0 1 2 3 4 6 5 3 2 7 imax: 0 max: 6

0 1 2 3 4 6 5 3 2 7 imax: 0 max: 6

0 1 2 3 4 6 5 3 2 7 imax: 0 max: 6

0 1 2 3 4 6 5 3 2 7 imax: 0 max: 6

0 1 2 3 4 6 5 3 2 7 imax: 0 max: 6

0 1 2 3 4 2 5 3 6 7 imax: 0 max: 6

0 1 2 3 4 2 5 3 6 7 imax: 0 max: 6

0 1 2 3 4 2 5 3 6 7 imax: 0 max: 2

0 1 2 3 4 2 5 3 6 7 imax: 0 max: 2

0 1 2 3 4 2 5 3 6 7 imax: 1 max: 5

0 1 2 3 4 2 5 3 6 7 imax: 1 max: 5

0 1 2 3 4 2 3 5 6 7 imax: 1 max: 5

0 1 2 3 4 2 3 5 6 7 imax: 1 max: 5

0 1 2 3 4 2 3 5 6 7 imax: 0 max: 2

0 1 2 3 4 2 3 5 6 7 imax: 0 max: 2

0 1 2 3 4 2 3 5 6 7 imax: 1 max: 3

0 1 2 3 4 2 3 5 6 7 imax: 1 max: 3

0 1 2 3 4 2 3 5 6 7 imax: 1 max: 3

void razeni_max_prvek(int *pole, int n) { } int i,j,index_max,d; for(i=n-1;i>=1;i--) { index_max = 0; for(j=1;j<=i;j++) if(pole[j]>pole[index_max]) index_max=j; d=pole[index_max]; pole[index_max]=pole[i]; pole[i]=d; }

Řazení záměnou (bublinkové řazení) (Bubble Sort) porovnáváme postupně v celém poli dva sousední prvky; pokud nejsou ve správném pořadí, zaměníme je po tomto kroku je na posledním místě pole největší prvek ( probublá na konec) krok algoritmu probublávání aplikujeme na postupně na pole o délce n-1, n- 2,,1

0 1 2 3 6 7 3 2

porovnám 0 1 2 3 6 7 3 2

porovnám 0 1 2 3 6 7 3 2

prohodím 0 1 2 3 6 7 3 2

prohodím 0 1 2 3 6 3 7 2

porovnám 0 1 2 3 6 3 7 2

prohodím 0 1 2 3 6 3 7 2

prohodím 0 1 2 3 6 3 2 7

0 1 2 3 6 3 2 7

0 1 2 3 6 3 2 7

porovnám 0 1 2 3 6 3 2 7

prohodím 0 1 2 3 6 3 2 7

prohodím 0 1 2 3 3 6 2 7

porovnám 0 1 2 3 3 6 2 7

prohodím 0 1 2 3 3 6 2 7

prohodím 0 1 2 3 3 2 6 7

0 1 2 3 3 2 6 7

0 1 2 3 3 2 6 7

porovnám 0 1 2 3 3 2 6 7

prohodím 0 1 2 3 3 2 6 7

prohodím 0 1 2 3 2 3 6 7

0 1 2 3 2 3 6 7

void bublinka(int *pole, int n) { int i,j,d; for(i=n-1;i>=1;i--) { for(j=0;j<=i-1;j++) if(pole[j]>pole[j+1]) { d=pole[j]; pole[j]=pole[j+1]; pole[j+1]=d; } } }

bublinkové řazení se dá vylepšit: pokud jsme při průchodu polem neprovedli ani jedenkrát záměnu, pole je seřazené a cyklus předčasně ukončíme bublání provádíme oběma směry (i k nižším indexům) Domácí úkol: vylepšete bublinkové řazení

void bublinka2(int *pole, int n) { int i,j,d; int prohozeno=1; for(i=n-1;i>=1 && prohozeno;i--) { prohozeno = 0; for(j=0;j<=i-1;j++) if(pole[j]>pole[j+1]) { prohozeno = 1; d=pole[j]; pole[j]=pole[j+1]; pole[j+1]=d; } } }

odhadněte operační složitost bublinkového řazení a řazení výběrem maximálního prvku O(n 2 )

problémy, které lze řešit (vyzkoušením všech možností) v polynomiálním čase, se nazývají P-problémy mnoho problémů v polynomiálním čase řešit nelze (mají nepolynomiální složitost) u některých existuje ale nedeterministický algoritmus, který je řeší v polynomiálním čase (NP nedeterministicky polynomiální) není znám deterministický algoritmus pro nalezení řešení: NP- úplné problémy (NP- complete)

Bohužel, většina reálných a zajímavých problémů (i dopravních) je NP-úplných řeší se přibližnými metodami (heuristikami), metodami umělé inteligence, genetickými algoritmy aj.

Příklad NP problémů problém obchodního cestujícího odvozený: souřadnicová vrtačka testování obvodů - úplný test splnitelnost booleovských formulí hledání podmnožiny dep hledání všech cest mezi dvěma body Hanojské věže

Quick Sort nejrychlejší algoritmus řazení založen na technice řešení problémů rozděl a panuj (divide and conquer) oblast řešení se rozdělí na dvě (stejně) velké oblasti, vyřeší se na každé polovině zvlášť a spojí se do výsledného řešení

Aplikace rozděl a panuj na Quick-Sort 1. Vyber pivot prvek ve středu pole 2. Přeskup pole prvky menší než pivot přesuň nalevo od něj, prvky větší než pivot přesuň napravo od něj 3. Seřaď část pole nalevo a napravo od pivota řazení levé a pravé části pole se provádí stejnou technikou (výběr pivota, ) až k části pole o délce 1 nelze naprogramovat jinak než rekurzí

void Quick_sort(int l, int r, int *pole) { int pivot,d,i,j; if (l < r) { i = l; j = r; pivot = pole[(l+r)/2]; do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); Quick_sort(l,j-1,pole); Quick_sort(i+1,r,pole); } }

volání funkce Quick_sort(0,n-1,pole); nejrychlejší algoritmus řazení, složitost O(nlog 2 n) poznámka: často se při řazení nepřehazují prvky, ale vytváří se pole indexů

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 0 0 1 2 3 4 6 7 3 2 5 j: 4 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 0 0 1 2 3 4 6 7 3 2 5 j: 3 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 0 0 1 2 3 4 6 7 3 2 5 j: 3 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 0 0 1 2 3 4 2 7 3 6 5 j: 3 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 0 0 1 2 3 4 2 7 3 6 5 j: 3 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 7 3 6 5 j: 3 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 7 3 6 5 j: 3 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 7 3 6 5 j: 2 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 7 3 6 5 j: 2 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 3 7 6 5 j: 2 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 3 7 6 5 j: 2 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 3 7 6 5 j: 2 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); l: 0 r: 4 i: 1 0 1 2 3 4 2 3 7 6 5 j: 1 pivot: 3 i j

do { while (pole[i] < pivot) i++; while (pole[j] > pivot) j--; if (i < j) { d = pole[i]; pole[i] = pole[j]; pole[j] = d; } } while (i < j); QuickSort(l,j-1,pole); QuickSort(j+1,r,pole); l: 0 r: 4 i: 1 0 1 2 3 4 2 3 7 6 5 j: 1 pivot: QuickSort(0,0,pole) QuickSort(2,4,pole)

Mergesort (řazení slučováním) 1. Rozdělíme řazené pole na poloviny 2. Seřadíme každou polovinu 3. Obě seřazené poloviny sloučíme

Mergesort void Merge_sort(int l, int r, int *pole) // l - levý index, r - pravý index včetně { int i,j,k,q; int *s; if (l>=r) return; q = (l+r)/2; Merge_sort(l,q,pole); Merge_sort(q+1,r,pole);

Mergesort } // slučuji, s je pomocne pole s = (int*)malloc(sizeof(int)*(r-l+1)); i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; // kopirovani pole s zpet do casti pole od indexu l for(i=0;i<k;i++) pole[l++] = s[i]; free(s);

volání funkce void razeni_merge(int n, int pole[]) // n velikost pole { } Merge_sort(0,n-1,pole); složitost algoritmu řazení O(nlog 2 n) nevýhoda nutnost existence pomocného pole (větší paměťová složitost)

void Merge_sort(int l, int r, int *pole) // l - levý index, r - pravý index včetně { int i,j,k,q; int *s; if (l>=r) return; q = (l+r)/2; Merge_sort(l,q,pole); Merge_sort(q+1,r,pole); l: 0 r: 4 q: 2 0 1 2 3 4 7 6 3 2 5 l r

// slučuji, s je pomocne pole i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; i: 0 j: 3 k: 0 0 1 2 3 4 3 6 7 2 5 i j s: 2

// slučuji, s je pomocne pole i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; i: 1 j: 4 k: 1 0 1 2 3 4 3 6 7 2 5 i j s: 2 3

// slučuji, s je pomocne pole i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; i: 1 j: 5 k: 2 0 1 2 3 4 3 6 7 2 5 i j s: 2 3 5

// slučuji, s je pomocne pole i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; i: 1 j: 5 k: 2 0 1 2 3 4 3 6 7 2 5 i j s: 2 3 5

// slučuji, s je pomocne pole i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; i: 1 j: 5 k: 2 0 1 2 3 4 3 6 7 2 5 i j s: 2 3 5 6

// slučuji, s je pomocne pole i = l; j = q+1; k = 0; while(i<=q && j <= r) { if (pole[i]<pole[j]) s[k++] = pole[i++]; else s[k++] = pole[j++]; } // kopirovani zbytku poli - probehne jen jeden z cyklu while (i<=q) s[k++] = pole[i++]; while (j<=r) s[k++] = pole[j++]; i: 1 j: 5 k: 2 0 1 2 3 4 3 6 7 2 5 i j s: 2 3 5 6 7

Poznámky ke složitostem lineární zdvojnásobení velikosti problému vede k dvojnásobnému času výpočtu zrychlení počítače 2x urychlí řešení problému 2x kvadratická zdvojnásobení velikosti problému vede k čtyřnásobnému času výpočtu zrychlení počítače 2x urychlí řešení problému 1,414x

Poznámky ke složitostem předpokládejme, že 1 operace trvá 1us, počet operací je dán vztahem v 1. sloupci doba výpočtu: srovnej: počet atomů ve vesmíru se odhaduje na 10 80 a stáří vesmíru na 14 10 9 let) zdroj: přednášky ZDT, FIT ČVUT, doc. Kolář

Poznámky ke složitostem pro malé množství dat, resp. určité uspořádání dat může být asymptoticky pomalejší algoritmus rychlejší pokud aplikujeme bublinkové řazení s testem prohození na seřazenou posloupnost, vykoná se pouze n kroků, ale Quick-Sort vykoná n.log 2 n vždy pro malý rozměr pole u algoritmu Quick-Sort převáží konstanty režie související s rekurzivním voláním

Poznámky ke složitostem ale vždy existuje určité n 0, od kterého bude asymptoticky rychlejší algoritmus rychlejší bez ohledu na rychlost počítače, jazyk, překladač, výkon počítače, překladač,, mění konstanty vztahu, které posouvají bod n 0