SlideShare une entreprise Scribd logo
1  sur  21
Skripta
Algoritmi I structure podataka u C++
“Algoritmi sortiranja”
Autor: Adnan Goretić
Mail: adnan.goretic@gmail.com
Facebook: https://www.facebook.com/ado.svdc
Autor: Adnan Goretić (adnan.goretic@gmail.com)
SADRŽAJ
1. ALGORITMI SORTIRANJA (UVOD) 3
2.SORTIRANJE ZAMJENOM ELEMENATA 4
2.1 Sortiranje izborom najmanjeg elementa (Selection Sort) 3
2.2 Sortiranje zamjenom susjedih elemenata (Bubble Sort) 5
3. SORTIRANJE UMETANJEM 6
3.1 Jednostavno sortiranje umetanjem (Insertion Sort) 6
3.2 Višsestruko sortiranje umetanjem (Shell Sort) 7
4. REKURZIVNI ALGORITMI SORTIRANJA 9
4.1 Pomoćna procedura spajanja (Merge) 9
4.2 Sortiranje spajanjem (Merge Sort) 9
4.3 Brzo sortiranje (Quick Sort) 11
5. SORTIRANJE POMOĆU BINARNOG STABLA 13
5.1 Sortiranje obilaskom binarnog stabla traženja (Tree sort) 13
5.2 Sortiranje pomocu hrpe (Heap sort ) 14
6.SORTIRANJE U LINEARNOM VREMENU 16
6.1 Sortiranje brojanjem (Counting sort) 16
6.2 Radix sort 18
7. PITANJA I ZADACI 20
8. ZAKLJUČAK 20
9. LITERATURA 20
Autor: Adnan Goretić (adnan.goretic@gmail.com)
1. ALGORITMI SORTIRANJA
Uvod:
Prema definiciji algoritama sortiranja, oni predstavljaju svaki algoritam koji riješava problem
sortiranja. U ovom radu ćemo se baviti algoritmima koji svoj rad temelje na:
1) Sortiranje zamjenom elementa
2) Sortiranje umetanjem
3) Sortiranje rekurzivnim pozivom
4) Sortiranja pomoću binarnih stabala
5) Sortiranje u linearnom vremenu
2. SORTIRANJE ZAMJENOM ELEMENATA
Ovi algoritmi predstavljaju najjednostavnije algoritme za sortiranje. U ovu skupinu algoritama
izmeđuostalog spadaju: Selectrion sort (sortiranje izborom najmanjeg elementa) teBubble sort
(sortiranje zamjenom susjednih elemenata)
2.1 Selection Sort
Način rada:Algoritam svoj rad započinje tako sto se prvo pronadje najmanji element u nizu a
onda se pronađeni element zamjeni za prvim. Ovaj se postupak ponavlja toliko puta kolika je
dužina niza, bez obzira da li je niz već sortiran ili ne. Ovaj postupak se može vidjeti na slijedećoj
slici (slika br.1).
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.1 (prikaz rada selection sort-a) [1]
Algoritam se može implementirati na slijedeći način:
void selectionSort (int *a, int n)
{
int i, j, min;
for (i = 0; i < n; i++) {
min = i;
for (j = i+1; j < n; j++)
if (a[ j ] < a[min]) min = j;
zamjena(&a[i], &a[min]);}}
Algoritam koristi I pomoćnu funkciju zamjena čiji je kod slijedeći:
void zamjena (int *x, int *y){
int aux;
aux = *x;
*x = *y;
*y = aux;}
Što se tiče vremenske složenosti algoritma, možemo reći da je algoritam uglavnom spor, I da vrši
poređenje bez obzira na početno stanje niza tj. bez obriza da li je niz već sortiran ili ne. Ukupan
broj operacija se može zapisati I matematičkom forulom:
n(n — 1)/2 + 3(n — 1) = O(n2).
Autor: Adnan Goretić (adnan.goretic@gmail.com)
2.2 Bubble Sort
Algoritam radi na slijedeći način:Prolazi nizom od početka prema kraju I uspređuje susjedne
elemente. Ako je neki element veći od slijedećeg izvrši se zamjena. Kada dođe do kraja niza
najveća vrijednost će biti na zadnjem mjestu. Jedina prednost u pogledu na selection sort, ovaj
algoritam se može zaustaviti čim se ustanovi da nema više elemenata za zamjenu. Ova činjenica
neće promjeniti ocjenu vremenske složenosti, ali će u velikoj mjeri doprinjeti brzem radu
algoritma.
Način rada algoritma možemo primjetiti na slijedećoj slici (slika br.2).
Slika br.2 ( prikaz rada bubble sort algoritma) [1]
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Algoritam se može implementirati slijedećim kodom:
void bubbleSort (int *a, int n){
int i, j;
for (i = 0; i < n-1; i++){
for (j = 0; j < n-1-i; j++){
if (a[j+1] < a[j])
zamjena(&a[j], &a[j+1]);
}}};
Ova verzija algoritma se može poboljšati, na taj način što će se sortiranje završiti čim se ustanovi
da nema više elemenata za zamjenu. Kod poboljšane verzije izgleda ovako:
void bubbleSort (int *a, int n){
int i, j, chg;
for (i = 0, chg = 1; chg; i++) {
chg = 0;
for (j = 0; j < n-1-i; j++)
if (a[j+1] < a[j]) {
zamjena(&a[j], &a[j+1]);
chg = 1;
}}};
Analiza vremenske složenosti ovog algoritma bi se mogla prikazati matematičkom formulom:
4(n − 1) + 4(n − 2) + · · ·+ 4·1 = 4n(n − 1)/2 = 2n(n − 1).
U svakom slučaju ocjena je ista kao i kod selection sort-a, značiO(n2).
3. SORTIRANJE UMATANJEM
Rad ovih algoritama se svodi na umetanje novog elementa u već sortirani niz. U ovoj skupini
algoritama imamo:Insertion sort (jednostavno sortiranje umetanjem) i Shell sort (višestruko
sortiranje umetanjem)
3.1 Insertion Sort
Rad ovog algoritma se može objasiniti na slijedeći način: algoritam uzima prvi element iz ne
sortiranog dijela te ga umetne u sortirani dio na svoje odgovarajuće mjesto. Sa ovom operacijom
se dužina sortiranog dijela niza sa svakom interacijom povećava za 1 dok se dužina ne sortiranog
dijela smanjuje za 1. Princip rada se može vidjeti na slijedećoj slici.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.3 (prikaz rada Insertion sort-a) [1]
Insertion sort se može implementirati slijedećim kodom:
void insertionSort (int *a, int n){
int i, j;
int aux;
for (i = 1; i < n; i++) {
aux = a[i];
for (j = i; j >= 1 && a[j-1] > aux; j--)
a[j] = a[j-1];
a[j] = aux;
}};
Što se vremenske složenosti tiče, ovaj algoritam ima istu ocjenu kao selection I bubble sort tj.
O(n2) ali se u praksi ipak pokazao mnogo bržim nego što je to prikazanom ocjenom brzine.
3.2 Shell Sort
Shell sort se bazira na Inserion sort-u. To se najbolje vidi iz koda Shell sort-a gdje je dodana
samo jedna dodatna for petlja. Ovaj algoritam radi tako što početni niz razdvaja na grupe
(tzv.subsort-ove) koji su međusobno udaljeni razmakom kojeg ćemo označiti sa k. Sada se na
svakoj od ovih grupa primjenjuje Insertion sort. Ovim radnjama se smanjuje broj grupa ali se
povćava broj elemenata u grupi. Svaka slijedeća grupa ima veći broj elemenata sa većim
stepenom uređenosti. Rad algoritma se vidi na slijedećoj slici.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.4 (prikaz rada Shell sort-a) [1]
Algoritam se može implementirati slijedećim kodom:
void ShellSort (int *a, int n){
int i, j, step;
int aux;
for (step = n/2; step > 0; step /= 2) {
for (i = step; i < n; i++) {
aux = a[i];
for (j = i; j >= step && a[j-step] > aux; j -= step)
a[j] = a[j-step];
a[j] = aux;}}};
Kao što možemo primjetiti, nije bilo velikih izmjena u odnosu na Insertion sort osim jedne
dodatne for petlje. Što se tiče složenosti algoritma, on predstavlja veliku nepoznanicu za
istraživače.Za ovaj algoritam još uvijek ne postoje jasne ocjene složenosti. Iz razpoloživih ocjena
može se zaključiti da je složenost u najgorem slučaju O(n3/2) što je bolje nego kod dosada
opisanih algoritama. Eksperimentalna mjerila pokazuju da je algoritam izuzetno brz u svakom
slučaju brži nego što to pokazuju raspoložive cojene.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
4. REKURZIVNI ALGORITMI SORTIRANJA
Rekurzivni algoritmi sortiranja su algoritmi koji u svrhu sortiranja pozivaju sami sebe. U ovu
grupu spadaju:Merge sort (sortiranje spajanjem) i Quick sort (brzo sortiranje)
4.1 Pomoćna procedura spajanja (Merge)
Ovaj postupak se odnosi na spajanje dva manja niza u jedan veći niz. Ovaj postupak predstavlja
pomoćnu proceduru u radu Merge sort-a. Može se implementirati sljedećim kodom:
void merge (int *c, int *aux, int l, int k, int r) {
int i, k1, count, aux;
k1 = k-1;
k2 = l;
count = r-l+1;
while (l <= k1 && k <= r) {
if (c[l] <= c[k]){
aux[k2++] = c[l++];}
else{
aux[k2++] = c[k++];}}
while (l <= k1)
aux[k2++] = c[l++];
while (k <= r)
aux[k2++] = c[k++];
for (i = 0; i < count; i++, r--),
c[r] = aux[r];}
4.2 Sortiranje spajanjem (Merge Sort)
Pored toga što algoritam radi pomoću rekurzije, njegov rad se isto bazira na dijeljenju niza na dva
manja niza podjednakih dužina, nad kojima se vrši rekurzivni poziv Merge sort-a. Nakon toga se
ta dva manja niza spajaju u jedan. Princip rada algoritma se može najbolje uočiti na slijedećoj
slici.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.5 (prikaz rada Merge sort algoritma) [1]
Sam kod algoritma igleda ovako:
void mergeSort (int *a, int *aux, int left, int right) {
int mid;
if (left < right){
mid = (left + right) / 2;
mergeSort (a, aux, left, mid);
mergeSort (a, aux, mid+1, right);
merge (a, aux, left, mid+1, right);}}
Vremenska analiza složenosti Merge sort-a se može matematički prikazati formulom:
(log2 n + 1) · O(n) = O(n log n).
Zahvaljujući ovakvoj ocjeni radi se o jednom od najbrzih poznatih algoritama za sortiranje.
Prednost ovog algoritma prema drugim je ta što se može sortirati velika količina podataka koji su
pohranjeni na nekoj vanjskoj memoriji računara. Dok manu ovog algoritma čini veliki utrošak
memorije zbog kreiranja dodatnog niza spajanja potrebnog u procesu sortiranja.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
4.3 Quick Sort
Quick sort radi na slijedećem principu: izabere se jedan element u nizu, tzv.pivot. Svi ostali
elementi se razvrstavaju prema njemu zavisno o tome da li su veći ili manji od pivota.
Slika br.6 (podijela niza preko pivota) [1]
Da bi se niz moga do kraja sortirati, mora se izvrsiti rekurzivni poziv Quick sor algoritma na ljevi
niz odnosno manje od pivota, te na desni niz tj.veći od pivota.
Slika br.7 (zamjena elemenata preko pivota) [1]
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Ovaj postupak se može ilustrovati na slijedeći način.
Slika br.8 (sortiranje niza pomoću Quick sort-a) [1]
Quick sort se može implementirati slijedećim kodom:
void quickSort(int *a, int l, int r) {
int i,j;
if (l>=r) return;
i = l+1;
j = r;
while ((i <= j) && (i<=r) && (j>l)) {
while ((a[i] < a[l]) && (i<=r)) i++;
while ((a[j] > a[l]) && (j>l)) j--;
if (i<j)
zamjena(&a[i], &a[j]);}
if (i>r) {
zamjena(&a[r], &a[l]);
quickSort(a, l, r-1);}
else if (j<=l)
quickSort(a, l+1, r);}
else {
zamjena(&a[j], &a[l]);
quickSort(a, l, j-1);
quickSort(a, j+1, r);}
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Vremenska analiza složenosti pokazuje da je prosječno vrijeme izvšavanja Quick sort algoritma
O(n logn). Ova ocjena zavisi uglavnom od izabira pivota. U najčešćem slucaju pivot se bira na
mjestu prvog, zadnjeg ili nekog od elementa u sredini niza.
5. SORTIRANJE POMOĆU BINARNOG STABLA
U ovu grupu spadaju Tree sort I Heap sort. Oba ova algoritma svoj rad zasnivaju naubacivanju
elemenata u binarno stablo. Nakon tog postupka, se iz binarnog stable čitaju elementi u
sortiranom redosljedu. Razlika između ovih algoritama je u vrsti binarnog stable kojeg
koriste.Tree sort koristi binarno stablo traženja a Heap sort koristi hrpu kao binarno stablo.
5.1 Sortiranje obilaskom binarnog stabla traženja (Tree sort)
Tree sort algoritam se koristi pomoćnom funkcijom binarnog stabla inorder, koja posjećuje sve
cvorove stabla u zavisnosti da li su veći ili manji od korijena. Prvo one što su manji od korijena a
onda one što su veće od korijena.Upravo ova svojstva koristi Tree sort.Način rada tree sort-a je
sljedeći.Algoritam prvo kreira binarno stablo pretrage.Podaci iz niza se ubacuju u binarno stablo
pomocu inorder funkcije.Zatim se čitaju podaci iz binarnog stabla također funkcijom
inorder.Algoritam se može implementirati koristeci još dodatne pomoćne funkcije insert koja
dodaje novi cvor u binarno stablo. Algoritam Tree sort-a moze se prikazati kodom:
struct cvorliste{
int x;
cvorliste *korijen;
cvorliste *ljevo;
cvorliste *destno;
cvorliste(){korijen=NULL;}};
void treeSort (int *a, int n) {
int i, next;
cvorliste *tree;
tree = NULL;
for (i=0; i<n; i++)
tree = insert(a[i], tree);
next=0;
Inorder(tree, a, &next);}
cvorliste *insert (int x, cvorliste *korijen) {
if (korijen == NULL) {
node->element = x;
korijen -> ljevo = korijen -> destno = NULL;}
else if (x < korijen ->element)
korijen -> ljevo = insert(x, korijen -> ljevo);
else
korijen -> destno = insert(x, korijen -> destno);
return korijen;}
Autor: Adnan Goretić (adnan.goretic@gmail.com)
void Inorder (cvorliste * korijen, int *a, int *np) {
if (korijen!= NULL) {
Inorder(korijen -> ljevo, a, np);
a[*np] = korijen ->element;
*np += 1;
Inorder(korijen -> destno, a, np);}}
Analiza vremenske složenosti ovog algoritma pokazuje O(n log n) ocjenu. Međutim ova ocjena
vrijedi samo u prosječnom slučaju. U najgorem slučaju ocjena vremenske složenosti će biti
O(n2), tj. ako je početni niz podataka već sortiran.
5.2 Sortiranje pomocu hrpe (Heap sort)
Definicija hrpe: Hrpa predstavlja specijalnu formu binarnog stable koja mora zadovoljiti svojstvo
hrpe. Svojstvo hrpe predstavlja uvijet: ako je B dijete od A, onda je A[indeks] < B[indeks]. Ovo
svojstvo garantuje da je vrijednost korijena uvijek najmanja.
Algoritam radi na slijedeći način. Podaci iz niza kojeg zelimo sortirati prvo se redom ubacuju u
hrpu. Onda se podaci skidaju sa hrpe I vracaju nazad u niz. Upravo zbog svojstva hrpe, podaci
izlaze iz hrpe u sortiranom redosljedu.
Za ilustraciju Heap sort-a imamo niz brojeva 17, 31, 3, 43, 11, 24, 8, koji su prikazani na
slijedećoj slici.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.9 (prikaz rada Heap Sort algoritma) [1]
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Implementacija se vrši slijedećim kodom:
void heapSort (int *a, int n) {
int i;
buildHeap (a, n);
for (i = n; i >= 2; i--) {
swap(&a[0], &a[i-1]);
adjust(a, 0, i-1);}}
void buildHeap (int *a, int n) {
int i;
for (i = n/2-1; i >= 0; i--)
adjust(a, i, n);}
void adjust(int *a, int i, int n) {
int j;
int x;
j = 2*i+1;
x = a[i];
while (j <= n-1 ) {
if ((j < n-1) && (a[j] > a[j+1])) j++;
if (x <= a[j]) break;
a[(j-1)/2] = a[j];
j = 2*j+1;}
a[(j-1)/2] = x;}
Vremenska složenost Heap sort algoritma iznosi kao I kod Tree sort algoritma O (n log n).
Eksperimenti pokazuju da Heap sort spade među najbrze poznate algoritme za sortiranje I da
uspješno soritra velike količine podataka.
6.SORITANJE U LINEARNOM VREMENU
Prethodno su opisani algoritmi koji imaju vremensku složenost O(n2) i O(n log n). Ono što je
zajedničko za te algoritme je da se sortirani poredak ulaznih elemenata temelji na poređenju.
Postoje algoritmi sortiranja koji osim poređenja koriste i neke druge operacije. Ti algoritmi pod
određenim uvjetima mogu postići linearnu vremensku složenost. U ovu grupu alogitama spadaju
Counting sort i Radix sort.
6.1 Sortiranje brojanjem (Counting sort)
Counting sort (Algoritam sortiranja brojanjem) koristi pretpostavku da su elementi iz ulaznog
niza cjelobrojne vrijednosti iz raspona 0 do k, 0 <= a[i] <= k.
K-a prestavlja parameter koji se može izraziti formulom k=max-min+1, gdje max i min
predstavljaju maximalne i minimalne vrijednosti nekog niza.
Osnovni mehanizam rada algoritma se sastoji u tome da se za svaki ulazni element x odredi broj
elemenata iz niza koji su manji od x. To se koristi da se element x direktno pozicionira na svoje
odgovarajuće mjesto u sortiranom nizu.
Primjer Counting sort-a može se vidjeti na slijedećoj slici.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.10( Rad counting sort algoritma) [2]
Kod Caunting sort algoritma se može zapisati:
void CountingSort(int *a, int *b, int k, int duzina){
int *c=new int[k];
for(int i=0; i<k; i++){
c[i]=0;}
for(int j=0; j<duzina; j++){
c[a[j]]=c[a[j]]+1;}
for(int i=1; i<k; i++){
c[i]=c[i]+c[i-1];}
for(int j=duzina-1; j>=0; j--){
c[a[j]]=c[a[j]]-1;
b[c[a[j]]]=a[j];}}
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Vremenska analiza složenosti se može predstaviti sa formulom O(k+n). Ako se u obzir ume da se
counting sort koristi najčešće kada je k=O(n), onda je ukuona složenost O(n).
6.2 Radix sort
Ovaj algoritam svoj rad bazira na odvojenim analizama ulaznih elemenata I njihovih znakova na
odgovarajućim pozicijama. Ako predpostavimo da su ključevi prikazani ako decimalni brojevi,
gdje se za svaki prikaza koristi k decimala.Tako imamo dk-1, dk-2….d0.
Algoritam rad započinje tako da ključeve ne sortiranog niza prvo sortira po cifri d0. Ovo se vrsi
sve dok algoritam ne dodoje do vrijednosti dk-1. Sortiranje se obavlja tako da se uzimaju
elementi iz niza I svrstavaju se u 10 nizova: Q[0], Q[1], … Q[9]. U niz Q[0] se stavljaju elementi
cija je zadnja cifra 0, u Q[1] se stavljaju elementi čija je zadnja cifra 1 itd. Nakon ovakvog
razmjestraja svi mali nizovi se spajaju u jedan niz i to uzlazno Q[0], Q[1], … Q[9].
Algoritam se može implementirati slijedećim kodom:
void RadixSort(int *a, int n){
int *b=new int[n];
int m=0,eks=1;
for(int i=0; i<n; i++){
if(a[i]>m){
m=a[i];}
while(m/eks>0){
int korpa[10]={0};
for(int i=0; i<n; i++){
korpa[a[i]/eks%10]++;}
for(int i=0; i<10; i++){
korpa[i]+=korpa[i-1];}
for(int i=n-1; i>=0; i--){
b[korpa[a[i]/eks%10]--]=a[i];}
for(int i=0; i<n; i++){
a[i]=b[i];
eks*=10;}}}}
Vremenska složenost ovog algoritma je O(nk), I to samo ako je cifra k kostantna. Ako k nije
konstantan onda se vremenska složenost povećava u skladu sa k.
Autor: Adnan Goretić (adnan.goretic@gmail.com)
Slika br.11( Proces rada Counting sort-a) [3]
Autor: Adnan Goretić (adnan.goretic@gmail.com)
7. PITANJA I ZADACI
1. Usporedi način rada Selection sort-a i Bubble sort-a!
2. Šta predstavlja postupak Merge?
3. Objasni rad algoritama sa vremenskom složenosti O(n logn) ?
4. Koja je razlika između Insertion sort-a i Shell sort-a?
5. Koja to svojstva čine hrpu?
6. Objasni razliku izmedju Tree sort-a i Heap sort-a?
7. Na koji način radi Counting sort?
8. Na koji način radi Radix sort?
9. Ilustrovati rad algoritama sa O(n2
)vremenskom složenosti!
10. Šta utječe na vremensku složenost Quick sort algoritma?
8. ZAKLJUČAK
Algoritmi za sortiranje prema definiciji predstavljaju svaki algoritam koji izvršava sortiranje
elemenata nekog niza, liste ili drugog tipa podatka. Algoritme za sortiranje možemo razlikovati
na osnovu svoje složenosti. Algoritmi su, u ovom radu, hronološki poredani prema svojoj
složenosti. Ta hronologija mogla bi se predstaviti ujedno kao i historijat razvoja algoritama za
sortiranje. Svaki od algoritama ima sličnosti sa drugim ali ipak i velikih razlika, koje se uglavnom
projiciraju na vremensku zahtjevnost algoritma.
9. LITERATURA
[1] “Algoritmi i strukture podataka“, Robert Manger, Miljenko Marušić, Zagreb, 2007
[2] “Algorithms in C++”, Robert Sedgewick, Addison-Wesley, 2002
[3] “Algorithms, data structures, and problem solving with C++ “, Mark Allen Weiss, Addison-
Wesley Pub. Co., 1996
Autor: Adnan Goretić (adnan.goretic@gmail.com)
POPIS SLIKA
1 Prikaz rada selection sort-a 4
2 Prikaz rada bubble sort algoritma 5
3 Prikaz rada Insertion sort-a 7
4 Prikaz rada Shell sort-a 8
5 Prikaz rada Merge sort algoritma 10
6 Podijela niza preko pivota 11
7 Zamjena elemenata preko pivota 11
8 Sortiranje niza pomoću Quick sort-a 12
9 Prikaz rada Heap Sort algoritma 15
10 Rad counting sort algoritma) 17
11 Proces rada Counting sort 19

Contenu connexe

Tendances

Grčko persijski ratovi
Grčko   persijski ratoviGrčko   persijski ratovi
Grčko persijski ratoviandjelan1
 
Digitalni prikaz zvuka i slike
Digitalni prikaz zvuka i slikeDigitalni prikaz zvuka i slike
Digitalni prikaz zvuka i slikeKristinaGoranovi
 
Revolucija 1848 1849.
Revolucija 1848 1849.Revolucija 1848 1849.
Revolucija 1848 1849.andjelan
 
Razvoj srednjovekovnih monarhija
Razvoj srednjovekovnih monarhijaRazvoj srednjovekovnih monarhija
Razvoj srednjovekovnih monarhijaandjelan
 
Zlatno doba atine i peloponeski rat
Zlatno doba atine i peloponeski ratZlatno doba atine i peloponeski rat
Zlatno doba atine i peloponeski ratandjelan1
 
REFORMACIJA I PROTIVREFORMACIJA
REFORMACIJA I PROTIVREFORMACIJAREFORMACIJA I PROTIVREFORMACIJA
REFORMACIJA I PROTIVREFORMACIJATihomir Bogović
 
Стара Грчка и Mакедонија
Стара Грчка и  MакедонијаСтара Грчка и  Mакедонија
Стара Грчка и MакедонијаŠule Malićević
 
ПРВИ РАЗРЕД - Стара Грчка и Стари Рим
ПРВИ РАЗРЕД - Стара Грчка и Стари Рим ПРВИ РАЗРЕД - Стара Грчка и Стари Рим
ПРВИ РАЗРЕД - Стара Грчка и Стари Рим Šule Malićević
 
Српска револуција (1804 - 1835) и Србија од 185 до 1878.
Српска револуција (1804 - 1835) и Србија од 185 до 1878.Српска револуција (1804 - 1835) и Србија од 185 до 1878.
Српска револуција (1804 - 1835) и Србија од 185 до 1878.Šule Malićević
 
Grčki polisi
Grčki polisiGrčki polisi
Grčki polisiandjelan
 
Kraj antičkog sveta i stvaranje varvarskih država
Kraj antičkog sveta i stvaranje varvarskih državaKraj antičkog sveta i stvaranje varvarskih država
Kraj antičkog sveta i stvaranje varvarskih državaPavle Nikolic
 
Други светски рат
Други светски ратДруги светски рат
Други светски ратUcionica istorije
 
Наполеоново доба
Наполеоново добаНаполеоново доба
Наполеоново добаUcionica istorije
 
Vladavina ustavobranitelja
Vladavina ustavobraniteljaVladavina ustavobranitelja
Vladavina ustavobraniteljaDušan Novakov
 
Knez - Kralj Milan Obrenovic - rad ucenika
Knez - Kralj Milan Obrenovic - rad ucenikaKnez - Kralj Milan Obrenovic - rad ucenika
Knez - Kralj Milan Obrenovic - rad ucenikaSanja Mladenovic
 

Tendances (20)

Грчко персијски ратови.Пелопонески рат.
Грчко персијски ратови.Пелопонески рат.Грчко персијски ратови.Пелопонески рат.
Грчко персијски ратови.Пелопонески рат.
 
Grčko persijski ratovi
Grčko   persijski ratoviGrčko   persijski ratovi
Grčko persijski ratovi
 
Digitalni prikaz zvuka i slike
Digitalni prikaz zvuka i slikeDigitalni prikaz zvuka i slike
Digitalni prikaz zvuka i slike
 
Revolucija 1848 1849.
Revolucija 1848 1849.Revolucija 1848 1849.
Revolucija 1848 1849.
 
Razvoj srednjovekovnih monarhija
Razvoj srednjovekovnih monarhijaRazvoj srednjovekovnih monarhija
Razvoj srednjovekovnih monarhija
 
Prvi svjetski rat
Prvi svjetski ratPrvi svjetski rat
Prvi svjetski rat
 
Prvi srpski ustanak
Prvi srpski ustanakPrvi srpski ustanak
Prvi srpski ustanak
 
Zlatno doba atine i peloponeski rat
Zlatno doba atine i peloponeski ratZlatno doba atine i peloponeski rat
Zlatno doba atine i peloponeski rat
 
REFORMACIJA I PROTIVREFORMACIJA
REFORMACIJA I PROTIVREFORMACIJAREFORMACIJA I PROTIVREFORMACIJA
REFORMACIJA I PROTIVREFORMACIJA
 
Стара Грчка и Mакедонија
Стара Грчка и  MакедонијаСтара Грчка и  Mакедонија
Стара Грчка и Mакедонија
 
ПРВИ РАЗРЕД - Стара Грчка и Стари Рим
ПРВИ РАЗРЕД - Стара Грчка и Стари Рим ПРВИ РАЗРЕД - Стара Грчка и Стари Рим
ПРВИ РАЗРЕД - Стара Грчка и Стари Рим
 
Српска револуција (1804 - 1835) и Србија од 185 до 1878.
Српска револуција (1804 - 1835) и Србија од 185 до 1878.Српска револуција (1804 - 1835) и Србија од 185 до 1878.
Српска револуција (1804 - 1835) и Србија од 185 до 1878.
 
VELIKA SEOBA NARODA
VELIKA SEOBA NARODA  VELIKA SEOBA NARODA
VELIKA SEOBA NARODA
 
Grčki polisi
Grčki polisiGrčki polisi
Grčki polisi
 
Kraj antičkog sveta i stvaranje varvarskih država
Kraj antičkog sveta i stvaranje varvarskih državaKraj antičkog sveta i stvaranje varvarskih država
Kraj antičkog sveta i stvaranje varvarskih država
 
Србија у првом светском рату
Србија у првом светском ратуСрбија у првом светском рату
Србија у првом светском рату
 
Други светски рат
Други светски ратДруги светски рат
Други светски рат
 
Наполеоново доба
Наполеоново добаНаполеоново доба
Наполеоново доба
 
Vladavina ustavobranitelja
Vladavina ustavobraniteljaVladavina ustavobranitelja
Vladavina ustavobranitelja
 
Knez - Kralj Milan Obrenovic - rad ucenika
Knez - Kralj Milan Obrenovic - rad ucenikaKnez - Kralj Milan Obrenovic - rad ucenika
Knez - Kralj Milan Obrenovic - rad ucenika
 

En vedette

天母國小英語每週一句設計理念
天母國小英語每週一句設計理念天母國小英語每週一句設計理念
天母國小英語每週一句設計理念Cindy Shen
 
Emergence and transformation of digital utilities in the “smart” era
Emergence and transformation of digital utilities in the “smart” era Emergence and transformation of digital utilities in the “smart” era
Emergence and transformation of digital utilities in the “smart” era Capgemini
 
106上學期四年級英語教學計畫
106上學期四年級英語教學計畫106上學期四年級英語教學計畫
106上學期四年級英語教學計畫Cindy Shen
 
Calbayog journal February 2016
Calbayog journal February 2016Calbayog journal February 2016
Calbayog journal February 2016Calbayog Journal
 
Calbayog journal November 2015
Calbayog journal November 2015Calbayog journal November 2015
Calbayog journal November 2015Calbayog Journal
 
Calbayog journal March 2016
Calbayog journal March 2016Calbayog journal March 2016
Calbayog journal March 2016Calbayog Journal
 
Calbayog journal December 2015
Calbayog journal December 2015Calbayog journal December 2015
Calbayog journal December 2015Calbayog Journal
 

En vedette (8)

天母國小英語每週一句設計理念
天母國小英語每週一句設計理念天母國小英語每週一句設計理念
天母國小英語每週一句設計理念
 
Emergence and transformation of digital utilities in the “smart” era
Emergence and transformation of digital utilities in the “smart” era Emergence and transformation of digital utilities in the “smart” era
Emergence and transformation of digital utilities in the “smart” era
 
106上學期四年級英語教學計畫
106上學期四年級英語教學計畫106上學期四年級英語教學計畫
106上學期四年級英語教學計畫
 
Calbayog journal February 2016
Calbayog journal February 2016Calbayog journal February 2016
Calbayog journal February 2016
 
Calbayog journal November 2015
Calbayog journal November 2015Calbayog journal November 2015
Calbayog journal November 2015
 
Calbayog journal March 2016
Calbayog journal March 2016Calbayog journal March 2016
Calbayog journal March 2016
 
Calbayog journal December 2015
Calbayog journal December 2015Calbayog journal December 2015
Calbayog journal December 2015
 
Comprension de la_lectura1
Comprension de la_lectura1Comprension de la_lectura1
Comprension de la_lectura1
 

Algoritmi sortiranja u C++

  • 1. Skripta Algoritmi I structure podataka u C++ “Algoritmi sortiranja” Autor: Adnan Goretić Mail: adnan.goretic@gmail.com Facebook: https://www.facebook.com/ado.svdc
  • 2. Autor: Adnan Goretić (adnan.goretic@gmail.com) SADRŽAJ 1. ALGORITMI SORTIRANJA (UVOD) 3 2.SORTIRANJE ZAMJENOM ELEMENATA 4 2.1 Sortiranje izborom najmanjeg elementa (Selection Sort) 3 2.2 Sortiranje zamjenom susjedih elemenata (Bubble Sort) 5 3. SORTIRANJE UMETANJEM 6 3.1 Jednostavno sortiranje umetanjem (Insertion Sort) 6 3.2 Višsestruko sortiranje umetanjem (Shell Sort) 7 4. REKURZIVNI ALGORITMI SORTIRANJA 9 4.1 Pomoćna procedura spajanja (Merge) 9 4.2 Sortiranje spajanjem (Merge Sort) 9 4.3 Brzo sortiranje (Quick Sort) 11 5. SORTIRANJE POMOĆU BINARNOG STABLA 13 5.1 Sortiranje obilaskom binarnog stabla traženja (Tree sort) 13 5.2 Sortiranje pomocu hrpe (Heap sort ) 14 6.SORTIRANJE U LINEARNOM VREMENU 16 6.1 Sortiranje brojanjem (Counting sort) 16 6.2 Radix sort 18 7. PITANJA I ZADACI 20 8. ZAKLJUČAK 20 9. LITERATURA 20
  • 3. Autor: Adnan Goretić (adnan.goretic@gmail.com) 1. ALGORITMI SORTIRANJA Uvod: Prema definiciji algoritama sortiranja, oni predstavljaju svaki algoritam koji riješava problem sortiranja. U ovom radu ćemo se baviti algoritmima koji svoj rad temelje na: 1) Sortiranje zamjenom elementa 2) Sortiranje umetanjem 3) Sortiranje rekurzivnim pozivom 4) Sortiranja pomoću binarnih stabala 5) Sortiranje u linearnom vremenu 2. SORTIRANJE ZAMJENOM ELEMENATA Ovi algoritmi predstavljaju najjednostavnije algoritme za sortiranje. U ovu skupinu algoritama izmeđuostalog spadaju: Selectrion sort (sortiranje izborom najmanjeg elementa) teBubble sort (sortiranje zamjenom susjednih elemenata) 2.1 Selection Sort Način rada:Algoritam svoj rad započinje tako sto se prvo pronadje najmanji element u nizu a onda se pronađeni element zamjeni za prvim. Ovaj se postupak ponavlja toliko puta kolika je dužina niza, bez obzira da li je niz već sortiran ili ne. Ovaj postupak se može vidjeti na slijedećoj slici (slika br.1).
  • 4. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.1 (prikaz rada selection sort-a) [1] Algoritam se može implementirati na slijedeći način: void selectionSort (int *a, int n) { int i, j, min; for (i = 0; i < n; i++) { min = i; for (j = i+1; j < n; j++) if (a[ j ] < a[min]) min = j; zamjena(&a[i], &a[min]);}} Algoritam koristi I pomoćnu funkciju zamjena čiji je kod slijedeći: void zamjena (int *x, int *y){ int aux; aux = *x; *x = *y; *y = aux;} Što se tiče vremenske složenosti algoritma, možemo reći da je algoritam uglavnom spor, I da vrši poređenje bez obzira na početno stanje niza tj. bez obriza da li je niz već sortiran ili ne. Ukupan broj operacija se može zapisati I matematičkom forulom: n(n — 1)/2 + 3(n — 1) = O(n2).
  • 5. Autor: Adnan Goretić (adnan.goretic@gmail.com) 2.2 Bubble Sort Algoritam radi na slijedeći način:Prolazi nizom od početka prema kraju I uspređuje susjedne elemente. Ako je neki element veći od slijedećeg izvrši se zamjena. Kada dođe do kraja niza najveća vrijednost će biti na zadnjem mjestu. Jedina prednost u pogledu na selection sort, ovaj algoritam se može zaustaviti čim se ustanovi da nema više elemenata za zamjenu. Ova činjenica neće promjeniti ocjenu vremenske složenosti, ali će u velikoj mjeri doprinjeti brzem radu algoritma. Način rada algoritma možemo primjetiti na slijedećoj slici (slika br.2). Slika br.2 ( prikaz rada bubble sort algoritma) [1]
  • 6. Autor: Adnan Goretić (adnan.goretic@gmail.com) Algoritam se može implementirati slijedećim kodom: void bubbleSort (int *a, int n){ int i, j; for (i = 0; i < n-1; i++){ for (j = 0; j < n-1-i; j++){ if (a[j+1] < a[j]) zamjena(&a[j], &a[j+1]); }}}; Ova verzija algoritma se može poboljšati, na taj način što će se sortiranje završiti čim se ustanovi da nema više elemenata za zamjenu. Kod poboljšane verzije izgleda ovako: void bubbleSort (int *a, int n){ int i, j, chg; for (i = 0, chg = 1; chg; i++) { chg = 0; for (j = 0; j < n-1-i; j++) if (a[j+1] < a[j]) { zamjena(&a[j], &a[j+1]); chg = 1; }}}; Analiza vremenske složenosti ovog algoritma bi se mogla prikazati matematičkom formulom: 4(n − 1) + 4(n − 2) + · · ·+ 4·1 = 4n(n − 1)/2 = 2n(n − 1). U svakom slučaju ocjena je ista kao i kod selection sort-a, značiO(n2). 3. SORTIRANJE UMATANJEM Rad ovih algoritama se svodi na umetanje novog elementa u već sortirani niz. U ovoj skupini algoritama imamo:Insertion sort (jednostavno sortiranje umetanjem) i Shell sort (višestruko sortiranje umetanjem) 3.1 Insertion Sort Rad ovog algoritma se može objasiniti na slijedeći način: algoritam uzima prvi element iz ne sortiranog dijela te ga umetne u sortirani dio na svoje odgovarajuće mjesto. Sa ovom operacijom se dužina sortiranog dijela niza sa svakom interacijom povećava za 1 dok se dužina ne sortiranog dijela smanjuje za 1. Princip rada se može vidjeti na slijedećoj slici.
  • 7. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.3 (prikaz rada Insertion sort-a) [1] Insertion sort se može implementirati slijedećim kodom: void insertionSort (int *a, int n){ int i, j; int aux; for (i = 1; i < n; i++) { aux = a[i]; for (j = i; j >= 1 && a[j-1] > aux; j--) a[j] = a[j-1]; a[j] = aux; }}; Što se vremenske složenosti tiče, ovaj algoritam ima istu ocjenu kao selection I bubble sort tj. O(n2) ali se u praksi ipak pokazao mnogo bržim nego što je to prikazanom ocjenom brzine. 3.2 Shell Sort Shell sort se bazira na Inserion sort-u. To se najbolje vidi iz koda Shell sort-a gdje je dodana samo jedna dodatna for petlja. Ovaj algoritam radi tako što početni niz razdvaja na grupe (tzv.subsort-ove) koji su međusobno udaljeni razmakom kojeg ćemo označiti sa k. Sada se na svakoj od ovih grupa primjenjuje Insertion sort. Ovim radnjama se smanjuje broj grupa ali se povćava broj elemenata u grupi. Svaka slijedeća grupa ima veći broj elemenata sa većim stepenom uređenosti. Rad algoritma se vidi na slijedećoj slici.
  • 8. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.4 (prikaz rada Shell sort-a) [1] Algoritam se može implementirati slijedećim kodom: void ShellSort (int *a, int n){ int i, j, step; int aux; for (step = n/2; step > 0; step /= 2) { for (i = step; i < n; i++) { aux = a[i]; for (j = i; j >= step && a[j-step] > aux; j -= step) a[j] = a[j-step]; a[j] = aux;}}}; Kao što možemo primjetiti, nije bilo velikih izmjena u odnosu na Insertion sort osim jedne dodatne for petlje. Što se tiče složenosti algoritma, on predstavlja veliku nepoznanicu za istraživače.Za ovaj algoritam još uvijek ne postoje jasne ocjene složenosti. Iz razpoloživih ocjena može se zaključiti da je složenost u najgorem slučaju O(n3/2) što je bolje nego kod dosada opisanih algoritama. Eksperimentalna mjerila pokazuju da je algoritam izuzetno brz u svakom slučaju brži nego što to pokazuju raspoložive cojene.
  • 9. Autor: Adnan Goretić (adnan.goretic@gmail.com) 4. REKURZIVNI ALGORITMI SORTIRANJA Rekurzivni algoritmi sortiranja su algoritmi koji u svrhu sortiranja pozivaju sami sebe. U ovu grupu spadaju:Merge sort (sortiranje spajanjem) i Quick sort (brzo sortiranje) 4.1 Pomoćna procedura spajanja (Merge) Ovaj postupak se odnosi na spajanje dva manja niza u jedan veći niz. Ovaj postupak predstavlja pomoćnu proceduru u radu Merge sort-a. Može se implementirati sljedećim kodom: void merge (int *c, int *aux, int l, int k, int r) { int i, k1, count, aux; k1 = k-1; k2 = l; count = r-l+1; while (l <= k1 && k <= r) { if (c[l] <= c[k]){ aux[k2++] = c[l++];} else{ aux[k2++] = c[k++];}} while (l <= k1) aux[k2++] = c[l++]; while (k <= r) aux[k2++] = c[k++]; for (i = 0; i < count; i++, r--), c[r] = aux[r];} 4.2 Sortiranje spajanjem (Merge Sort) Pored toga što algoritam radi pomoću rekurzije, njegov rad se isto bazira na dijeljenju niza na dva manja niza podjednakih dužina, nad kojima se vrši rekurzivni poziv Merge sort-a. Nakon toga se ta dva manja niza spajaju u jedan. Princip rada algoritma se može najbolje uočiti na slijedećoj slici.
  • 10. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.5 (prikaz rada Merge sort algoritma) [1] Sam kod algoritma igleda ovako: void mergeSort (int *a, int *aux, int left, int right) { int mid; if (left < right){ mid = (left + right) / 2; mergeSort (a, aux, left, mid); mergeSort (a, aux, mid+1, right); merge (a, aux, left, mid+1, right);}} Vremenska analiza složenosti Merge sort-a se može matematički prikazati formulom: (log2 n + 1) · O(n) = O(n log n). Zahvaljujući ovakvoj ocjeni radi se o jednom od najbrzih poznatih algoritama za sortiranje. Prednost ovog algoritma prema drugim je ta što se može sortirati velika količina podataka koji su pohranjeni na nekoj vanjskoj memoriji računara. Dok manu ovog algoritma čini veliki utrošak memorije zbog kreiranja dodatnog niza spajanja potrebnog u procesu sortiranja.
  • 11. Autor: Adnan Goretić (adnan.goretic@gmail.com) 4.3 Quick Sort Quick sort radi na slijedećem principu: izabere se jedan element u nizu, tzv.pivot. Svi ostali elementi se razvrstavaju prema njemu zavisno o tome da li su veći ili manji od pivota. Slika br.6 (podijela niza preko pivota) [1] Da bi se niz moga do kraja sortirati, mora se izvrsiti rekurzivni poziv Quick sor algoritma na ljevi niz odnosno manje od pivota, te na desni niz tj.veći od pivota. Slika br.7 (zamjena elemenata preko pivota) [1]
  • 12. Autor: Adnan Goretić (adnan.goretic@gmail.com) Ovaj postupak se može ilustrovati na slijedeći način. Slika br.8 (sortiranje niza pomoću Quick sort-a) [1] Quick sort se može implementirati slijedećim kodom: void quickSort(int *a, int l, int r) { int i,j; if (l>=r) return; i = l+1; j = r; while ((i <= j) && (i<=r) && (j>l)) { while ((a[i] < a[l]) && (i<=r)) i++; while ((a[j] > a[l]) && (j>l)) j--; if (i<j) zamjena(&a[i], &a[j]);} if (i>r) { zamjena(&a[r], &a[l]); quickSort(a, l, r-1);} else if (j<=l) quickSort(a, l+1, r);} else { zamjena(&a[j], &a[l]); quickSort(a, l, j-1); quickSort(a, j+1, r);}
  • 13. Autor: Adnan Goretić (adnan.goretic@gmail.com) Vremenska analiza složenosti pokazuje da je prosječno vrijeme izvšavanja Quick sort algoritma O(n logn). Ova ocjena zavisi uglavnom od izabira pivota. U najčešćem slucaju pivot se bira na mjestu prvog, zadnjeg ili nekog od elementa u sredini niza. 5. SORTIRANJE POMOĆU BINARNOG STABLA U ovu grupu spadaju Tree sort I Heap sort. Oba ova algoritma svoj rad zasnivaju naubacivanju elemenata u binarno stablo. Nakon tog postupka, se iz binarnog stable čitaju elementi u sortiranom redosljedu. Razlika između ovih algoritama je u vrsti binarnog stable kojeg koriste.Tree sort koristi binarno stablo traženja a Heap sort koristi hrpu kao binarno stablo. 5.1 Sortiranje obilaskom binarnog stabla traženja (Tree sort) Tree sort algoritam se koristi pomoćnom funkcijom binarnog stabla inorder, koja posjećuje sve cvorove stabla u zavisnosti da li su veći ili manji od korijena. Prvo one što su manji od korijena a onda one što su veće od korijena.Upravo ova svojstva koristi Tree sort.Način rada tree sort-a je sljedeći.Algoritam prvo kreira binarno stablo pretrage.Podaci iz niza se ubacuju u binarno stablo pomocu inorder funkcije.Zatim se čitaju podaci iz binarnog stabla također funkcijom inorder.Algoritam se može implementirati koristeci još dodatne pomoćne funkcije insert koja dodaje novi cvor u binarno stablo. Algoritam Tree sort-a moze se prikazati kodom: struct cvorliste{ int x; cvorliste *korijen; cvorliste *ljevo; cvorliste *destno; cvorliste(){korijen=NULL;}}; void treeSort (int *a, int n) { int i, next; cvorliste *tree; tree = NULL; for (i=0; i<n; i++) tree = insert(a[i], tree); next=0; Inorder(tree, a, &next);} cvorliste *insert (int x, cvorliste *korijen) { if (korijen == NULL) { node->element = x; korijen -> ljevo = korijen -> destno = NULL;} else if (x < korijen ->element) korijen -> ljevo = insert(x, korijen -> ljevo); else korijen -> destno = insert(x, korijen -> destno); return korijen;}
  • 14. Autor: Adnan Goretić (adnan.goretic@gmail.com) void Inorder (cvorliste * korijen, int *a, int *np) { if (korijen!= NULL) { Inorder(korijen -> ljevo, a, np); a[*np] = korijen ->element; *np += 1; Inorder(korijen -> destno, a, np);}} Analiza vremenske složenosti ovog algoritma pokazuje O(n log n) ocjenu. Međutim ova ocjena vrijedi samo u prosječnom slučaju. U najgorem slučaju ocjena vremenske složenosti će biti O(n2), tj. ako je početni niz podataka već sortiran. 5.2 Sortiranje pomocu hrpe (Heap sort) Definicija hrpe: Hrpa predstavlja specijalnu formu binarnog stable koja mora zadovoljiti svojstvo hrpe. Svojstvo hrpe predstavlja uvijet: ako je B dijete od A, onda je A[indeks] < B[indeks]. Ovo svojstvo garantuje da je vrijednost korijena uvijek najmanja. Algoritam radi na slijedeći način. Podaci iz niza kojeg zelimo sortirati prvo se redom ubacuju u hrpu. Onda se podaci skidaju sa hrpe I vracaju nazad u niz. Upravo zbog svojstva hrpe, podaci izlaze iz hrpe u sortiranom redosljedu. Za ilustraciju Heap sort-a imamo niz brojeva 17, 31, 3, 43, 11, 24, 8, koji su prikazani na slijedećoj slici.
  • 15. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.9 (prikaz rada Heap Sort algoritma) [1]
  • 16. Autor: Adnan Goretić (adnan.goretic@gmail.com) Implementacija se vrši slijedećim kodom: void heapSort (int *a, int n) { int i; buildHeap (a, n); for (i = n; i >= 2; i--) { swap(&a[0], &a[i-1]); adjust(a, 0, i-1);}} void buildHeap (int *a, int n) { int i; for (i = n/2-1; i >= 0; i--) adjust(a, i, n);} void adjust(int *a, int i, int n) { int j; int x; j = 2*i+1; x = a[i]; while (j <= n-1 ) { if ((j < n-1) && (a[j] > a[j+1])) j++; if (x <= a[j]) break; a[(j-1)/2] = a[j]; j = 2*j+1;} a[(j-1)/2] = x;} Vremenska složenost Heap sort algoritma iznosi kao I kod Tree sort algoritma O (n log n). Eksperimenti pokazuju da Heap sort spade među najbrze poznate algoritme za sortiranje I da uspješno soritra velike količine podataka. 6.SORITANJE U LINEARNOM VREMENU Prethodno su opisani algoritmi koji imaju vremensku složenost O(n2) i O(n log n). Ono što je zajedničko za te algoritme je da se sortirani poredak ulaznih elemenata temelji na poređenju. Postoje algoritmi sortiranja koji osim poređenja koriste i neke druge operacije. Ti algoritmi pod određenim uvjetima mogu postići linearnu vremensku složenost. U ovu grupu alogitama spadaju Counting sort i Radix sort. 6.1 Sortiranje brojanjem (Counting sort) Counting sort (Algoritam sortiranja brojanjem) koristi pretpostavku da su elementi iz ulaznog niza cjelobrojne vrijednosti iz raspona 0 do k, 0 <= a[i] <= k. K-a prestavlja parameter koji se može izraziti formulom k=max-min+1, gdje max i min predstavljaju maximalne i minimalne vrijednosti nekog niza. Osnovni mehanizam rada algoritma se sastoji u tome da se za svaki ulazni element x odredi broj elemenata iz niza koji su manji od x. To se koristi da se element x direktno pozicionira na svoje odgovarajuće mjesto u sortiranom nizu. Primjer Counting sort-a može se vidjeti na slijedećoj slici.
  • 17. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.10( Rad counting sort algoritma) [2] Kod Caunting sort algoritma se može zapisati: void CountingSort(int *a, int *b, int k, int duzina){ int *c=new int[k]; for(int i=0; i<k; i++){ c[i]=0;} for(int j=0; j<duzina; j++){ c[a[j]]=c[a[j]]+1;} for(int i=1; i<k; i++){ c[i]=c[i]+c[i-1];} for(int j=duzina-1; j>=0; j--){ c[a[j]]=c[a[j]]-1; b[c[a[j]]]=a[j];}}
  • 18. Autor: Adnan Goretić (adnan.goretic@gmail.com) Vremenska analiza složenosti se može predstaviti sa formulom O(k+n). Ako se u obzir ume da se counting sort koristi najčešće kada je k=O(n), onda je ukuona složenost O(n). 6.2 Radix sort Ovaj algoritam svoj rad bazira na odvojenim analizama ulaznih elemenata I njihovih znakova na odgovarajućim pozicijama. Ako predpostavimo da su ključevi prikazani ako decimalni brojevi, gdje se za svaki prikaza koristi k decimala.Tako imamo dk-1, dk-2….d0. Algoritam rad započinje tako da ključeve ne sortiranog niza prvo sortira po cifri d0. Ovo se vrsi sve dok algoritam ne dodoje do vrijednosti dk-1. Sortiranje se obavlja tako da se uzimaju elementi iz niza I svrstavaju se u 10 nizova: Q[0], Q[1], … Q[9]. U niz Q[0] se stavljaju elementi cija je zadnja cifra 0, u Q[1] se stavljaju elementi čija je zadnja cifra 1 itd. Nakon ovakvog razmjestraja svi mali nizovi se spajaju u jedan niz i to uzlazno Q[0], Q[1], … Q[9]. Algoritam se može implementirati slijedećim kodom: void RadixSort(int *a, int n){ int *b=new int[n]; int m=0,eks=1; for(int i=0; i<n; i++){ if(a[i]>m){ m=a[i];} while(m/eks>0){ int korpa[10]={0}; for(int i=0; i<n; i++){ korpa[a[i]/eks%10]++;} for(int i=0; i<10; i++){ korpa[i]+=korpa[i-1];} for(int i=n-1; i>=0; i--){ b[korpa[a[i]/eks%10]--]=a[i];} for(int i=0; i<n; i++){ a[i]=b[i]; eks*=10;}}}} Vremenska složenost ovog algoritma je O(nk), I to samo ako je cifra k kostantna. Ako k nije konstantan onda se vremenska složenost povećava u skladu sa k.
  • 19. Autor: Adnan Goretić (adnan.goretic@gmail.com) Slika br.11( Proces rada Counting sort-a) [3]
  • 20. Autor: Adnan Goretić (adnan.goretic@gmail.com) 7. PITANJA I ZADACI 1. Usporedi način rada Selection sort-a i Bubble sort-a! 2. Šta predstavlja postupak Merge? 3. Objasni rad algoritama sa vremenskom složenosti O(n logn) ? 4. Koja je razlika između Insertion sort-a i Shell sort-a? 5. Koja to svojstva čine hrpu? 6. Objasni razliku izmedju Tree sort-a i Heap sort-a? 7. Na koji način radi Counting sort? 8. Na koji način radi Radix sort? 9. Ilustrovati rad algoritama sa O(n2 )vremenskom složenosti! 10. Šta utječe na vremensku složenost Quick sort algoritma? 8. ZAKLJUČAK Algoritmi za sortiranje prema definiciji predstavljaju svaki algoritam koji izvršava sortiranje elemenata nekog niza, liste ili drugog tipa podatka. Algoritme za sortiranje možemo razlikovati na osnovu svoje složenosti. Algoritmi su, u ovom radu, hronološki poredani prema svojoj složenosti. Ta hronologija mogla bi se predstaviti ujedno kao i historijat razvoja algoritama za sortiranje. Svaki od algoritama ima sličnosti sa drugim ali ipak i velikih razlika, koje se uglavnom projiciraju na vremensku zahtjevnost algoritma. 9. LITERATURA [1] “Algoritmi i strukture podataka“, Robert Manger, Miljenko Marušić, Zagreb, 2007 [2] “Algorithms in C++”, Robert Sedgewick, Addison-Wesley, 2002 [3] “Algorithms, data structures, and problem solving with C++ “, Mark Allen Weiss, Addison- Wesley Pub. Co., 1996
  • 21. Autor: Adnan Goretić (adnan.goretic@gmail.com) POPIS SLIKA 1 Prikaz rada selection sort-a 4 2 Prikaz rada bubble sort algoritma 5 3 Prikaz rada Insertion sort-a 7 4 Prikaz rada Shell sort-a 8 5 Prikaz rada Merge sort algoritma 10 6 Podijela niza preko pivota 11 7 Zamjena elemenata preko pivota 11 8 Sortiranje niza pomoću Quick sort-a 12 9 Prikaz rada Heap Sort algoritma 15 10 Rad counting sort algoritma) 17 11 Proces rada Counting sort 19