Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 13

Smer:Računarska tehnika

Predmet:Paralelni racunarski sistemi

Seminarski rad
Tema:Sortiranje

Profesor: Student:

Dr.Sinisa Randjić Goran Vasiljević 752/2008


Sadržaj:

1. Uvod....................................................................................................................................................3
2. Sortiranje izborom uzastopnih minimuma (selection sort)..................................................................4
3. Sortiranje umetanjem elemenata niza na odgovarajuća mesta (insertion-sort)..................................5
4. Sortiranje zamenom susednih elemenata (bubble sort)......................................................................7
5. Sortiranje korišćenjem drveta (heap sort)...........................................................................................9
6. Literatura...........................................................................................................................................13

2
1. Uvod

Jedan od najčešćih problema koji se javljaju u programiranju je sortiranje. Pod sortiranjem se


podrazumeva uređivanje u neopadajući (rastući) i nerastući (opadajući) poredak kolekcije nekih
podataka, koji se mogu porediti. Sortiranje se može vršiti nad različitim vrtama podataka:
 Kod numeričkih nizova red elemenata se obično uređuje od manjeg prema većim
elementima;
 Kod nizova stringova red se određuje prema leksikografskom rasporedu;
 Kod kolekcija strukturnog tipa obično se odabire jedan član strukture kao ključni element
sortiranja.

Zbog čestog pojavljivanja problem sortiranja je znatno izučavan usled čega je nastao veliki
broj algoritama za sortiranje.Algoritam sortiranja postavlja elemente neke liste u određeni
redosled.Efektivni algoritmi sortiranja preduslov su uspešnosti nekih drugih algoritama, npr.
onih algoritamapretraživanja koji zahtevaju sortiranu listu da bi se u njoj mogli pronaći neki
elementi. Većina algoritama sortiranja zasniva se na metodologiji „podeli pa vladaj“ ,to jest
ponavlja se postupak redukovanja složenog problema na više jednostavnijih manjih celina,
odnosno veliki niz se deli na više manjih nizova kojise zasebno sortiraju. Takvi zasebno
sortirani segmenti zatim se spajaju u konačno sortiran niz.Redukovanje niza se obično obavlja na
na rekurzivan način. Algoritmi sortiranja najviše se razlikuju u operacijama odnosno načinima
deljenja na podnizove i spajanja u konačno sortirani niz.

Postoji mnogo načina da se niz podataka uredi, od najelementarnijih do veoma kompleksnih


metoda. Izbor metode, odnosno algoritma, zavisi od procene "početnih uslova": ako se sortira
kratak niz podataka, lakše je izabrati elementarni metod koji ćete lako implementirati. Međutim,
ako se sortiranje ponavlja veliki broj puta ili se radi o ogromnim nizovima, brzina postaje jako
bitan, čak odlučujući faktor.

Takođe, značajan podatak je i količina dodatne memorije, neophodna za pojedine metode


sortiranja.Ovde je moguće izdvojiti tri slučaja. U prvom, sortiranje se odvija na "licu mesta",
odnosno dodatna memorija je neophodna za neki vrlo mali stek ili tabelu. Drugi slučaj je
karakterističan za algoritme koji koriste povezanu listu, pa im je, shodno tome, potrebna
memorija za još N (broj elemenata koji se sortiraju) pointera, a treći, memorijski najzahtevniji,
za algoritme kojima je neophodna kompletna kopija niza elemenata koji se sortiraju.

Postoji veliki broj algoritama za sortiranje a u ovom radu ćemo se baviti sa četiri vrste
sortiranja:
1. sortiranje izborom uzastopnih minimuma (selection-sort),
2. sortiranje zamjenom susednih elemenata (bubble-sort)
3. sortiranje umetanjem elemenata niza na odgovarajuća mesta (insertion-sort)
4. sortiranje korišćenjem drveta (heap-sort)

3
2. Sortiranje izborom uzastopnih minimuma (selection sort)
Metoda selekcije je jednostavan algoritam sortiranja koji ima bolje performanse odmnogo
složenijih algoritama sortiranja u određenim situacijama, kao što su primene zarad u realnom
vremenu ili kada je upis u memoriju značajno vremenski skuplji od čitanjaiz memorije (na
primer prilikom rada sa nizovima smeštenim u EEPROM ili Flash memoriji).Metoda slekcije
takođe ima visoke performanse kada je u pitanju rad sa malimnizovima (10-20 elemenata) gde je
brža čak i od podeli-pa-vladaj algoritama sortiranjakao što su quicksort ili mergesort. S toga je i
primena metode selekcije za “dovoljnomale“ ulazne podnizove korisna praktična optimizacija za
rekurzivne algoritme.

Algoritam sortiranja primenom metode selekcije obavlja svoju funkciju nadulaznim


nizom tako što se nad njim izvršava sledeće:u ulaznom nizu pronaći svaki element koji je manji
od onog koji se nalazi na prvom mestu i ako je manji zameniti ga s tim elementom koji je na
prvom mestu.Tako ćemo na kraju dobiti najmanji element na prvom mestu. Postupak se tako
dalje ponavlja za preostale elemente od drugog do zadnjeg mjesta. Znači dobijamopoređan niz
od najmanjeg elementa na prvom mestu, dok će na zadnjem mestu ostati najveći
element.Efektivno, mi u stvari delimo ulazni niz na dva dela: podniz već sortiranih
elemenata,koji gradimo s leva na desno i koji se nalazi na početku niza, i podniz elemenata koji
jošuvek nisu sortirani, koji zauzima ostatak ulaznog niza.Da bi se celi niz sortirao potrebno je n –
1prolazaka.

Slika 1 Primer sortiranja algoritmom izbora najmanjeg elementa

Primer sortiranja izborom najmanjeg elemenata (selection sort) vidi se na slici 1. U


svakomprolasku pronadeni najmanji element je osenčen. Posmatrani deoniza nalazi se s desne
strane vertikalne crte. Sedmi prolazak nije potreban jer je nakon šestog prolaska preostali deo
niza dužine 1.
Algoritam sortiranja izborom najmanjeg elementa (selection sort) može se u jeziku C
realizovatisledećom funkcijom selectionSort(). Ta funkcija prima kao argumente celobrojni niz
a[ ]i njegovu dužinu n. Funkcija menja niz a[ ] tako da ono postane sortirano. Pomoćna funkcija
swap() služi za zamenu vrednosti dve celobrojne promenljive sa zadanim adresama.
void selectionSort (int a[], int n) {

4
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;
}
swap(&a[i], &a[min]);
}
}

void swap (int *x, int *y) {


int pom;
pom = *x;
*x = *y;
*y = pom;
}

Analiza rada:
Metod selekcije je jednostavniji za analizu složenosti u odnosu na neke drugealgortime
sortiranja, zato što nijedna petlja u algoritmu ne zavisi od podataka u nizu.Da bi
odredilisloženost ovog algoritma treba naći nekakvu meru njegove brzine i odrediti od čega ta
brzina zavisi. Jasno je da dužina niza N ima presudan značaj. Manji značaj ima i tip elemenata
niza, jer za neke složenije tipove podataka upoređivanje je puno komplikovanije nego za
nekejednostavnije tipove podataka. Nadalje, u ovoj jednostavnoj analizi, gledaćemo samo
uticajdužine niza N.
U prvoj iteraciji spoljne petlje po brojaču i, imamo N −1 ponavljanja unutrašnje petlje po
brojaču j. Svaki sledeći put imamo jedno ponavljanje manje. Sada mozemo izračunati
brojponavljanja Us:

( N −1 ) N N 2−N
Us = (N - 1) + (N - 2) + … + 3 + 2 + 1 = =
2 2

Ovu jednakost je lako dokazati ako saberemo prvi član sume sa zadnjim, drugi sa
predzadnjim itd.Na kraju, zaključimo da je algoritam“selection-sort” tzv. “kvadratnesloženosti”,
tj.nazovimo tako ovu klasu sporijihalgoritama za sortiranje. Vidimo da ni to što se od N 2
oduzima N i to svedeli s dva ne pomaže puno, tj. i dalje imamo ‘dosta spor’ algoritam.

3. Sortiranje umetanjem elemenata niza na odgovarajuća


mesta (insertion-sort)
5
Za vreme rada algoritma, početni komad niza je već sortiran, a ostatak niza nije sortiran. U
jednomprolasku algoritam uzima prvi element iz nesortiranog dela, te ga umetne na “pravo
mesto” (u smislu sortiranog redosleda) u sortirani deo, pri čemu dolazi do pomicanja nekih
elemenata za jedno mestodalje. Dakle, jednim prolaskom dužina početnog sortiranog dela se
poveća za 1, a dužina nesortiranog dela se smanji za 1.

Slika 2Primer jednostavnog sortiranja umetanjem.

Primer rada jednostavnog algoritma za sortiranje umetanjem (insertion sort-a) vidi se na


slici 2.U svakom prolasku, element iz nesortiranog dela polja koji se umeće u sortirani
deooznačen jesenčcanjem. Mesto umetanja označeno je strelicom. Sortirani deo polja nalazi se s
leve stranevertikalne crte, a nesortirani s desne strane.Implementacija jednostavnog sortiranja
umetanjem (insertion sort) u jeziku C svodi se na sledećufunkciju insertionSort(). Funkcija opet
kao argument prima celobrojniniza[ ] kojeg trebasortirati, te njegovu dužinun.

void insertionSort (int a[], int n) {


int i, j;
intpom;
for (i = 1; i < n; i++) {
pom = a[i];
for (j = i; j >= 1 && a[j-1] >pom; j--)
a[j] = a[j-1];
a[j] = pom;
}
}

6
Sledi analiza vremenske složenosti jednostavnog algoritma za sortiranje umetanjem
(insertionsort).
- U k-tom prolasku natraške prolazimo sortiranim delom nizadužinek. Zatečene
elementepomičemo za jedno mesto dalje dok god su oni veći od elementa kojeg želimo umetnuti
na“pravo mesto”. To u najgorem slučaju daje k upoređivanja i otprilike isto toliko pridruživanja.
- Dakle ukupni broj operacija u najgorem slučaju je otprilike

2 · 1 + 2 · 2 + · · ·+ 2(n − 1) = n(n − 1).

- Red veličine za vreme izvodenja je opet O(n2). Uprkos takvoj asimptotskoj oceni, ovaj
algoritamse u praksi ipak pokazuje bržim od pre opisanog algoritma sa zamenom elemenata.

4. Sortiranje zamenom susednih elemenata (bubble sort)


Ovo je jedna od najjednostavnijih metoda sortiranja koja efikasno funkcioniše samo sa
relativno malim brojem elemenata koji se sortira. Za veći broj elemenata ova metoda je
prespora.Stoga se ova metoda vrlo retko upotrebljiva osim za edukativne svrhe.
Opis algoritma ide ovako.Niz koji treba sortirati ima n elemenata. Prolazimo nizom od
početka prema kraju i upoređujemo susedne elemente.Ako je neki element veći od sledećeg
elementa, zamenimo im vrednosti. Kad na taj način dođemo do kraja niza, najveća vrednost doći
će na poslednje mesto. Nakon toga ponavljamo postupak na skraćenom nizu (bez zadnjeg
elementa). Algoritam se sme zaustaviti čim on u nekom prolazu ustanovi da nema parova
elemenata koje bi trebalo zameniti.
Primer sortiranja zamenom susednih elemenata (bubble sort) vidi se na slici 3. U svakom
koraku dva susedna elementa koji trebaju zameniti vrednosti označeni su osenčano. Posmatrani
deo niza nalazi se sa leve strane vertikalne crte. Šesti prolaz služi zato da se ustanovi da
višenema parova susednih elemenata koje bi trebalo zameniti.

7
Slika 3. Primer sortiranja algoritmom zamene susednih elemenata

Sledeća funkcija bubbleSort() implementira algoritam sortiranja zamenom susednih


elemenata(bubble sort) u jeziku C. Funkcija opet prima kao argumente celobrojni niz a[ ] i
njegovu dužinun, te menja niz a[ ] tako da ono postane sortirano. Koristi se ista pomoćna
funkcija swap() zazamenu vrednosti dve celobrojne promenljive kao i pre.

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])
swap(&a[j], &a[j+1]);
}

Implementacija se može poboljšati tako da se postupak zaustavi čim se ustanovi da u


nekom prolazu nije bilo ni jedne zamene susednih elemenata. Poboljšana verzija
funkcijebubbleSort() izgleda ovako.

void bubbleSort1 (int a[], int n) {


int i, j, pom;
for (i = 0, pom = 1; pom; i++) {
pom = 0;
for (j = 0; j < n-1-i; j++)
if (a[j+1] < a[j]) {
swap(&a[j], &a[j+1]);
pom = 1;
}
}
}

U nastavku sledi analiza vremenske složenosti opisanog algoritma sortiranja zamenom


susednihelemenata (bubble sort).
- U prvom prolazu imamo u najgorem slučaju n − 1 upoređivanja i n − 1 zamena
elemenata.
- U drugom prolazu imamo u najgorem slučaju n − 2 upoređivanja i n − 2 zamena
elemenata.
-.......
- U (n − 1)-vom prolazu imamo u najgorem slučaju 1 upoređivanje i 1 zamenu elemenata.
- Dakle ukupan broj operacija u najgorem slučaju iznosi:

4(n − 1) + 4(n − 2) + · · ·+ 4·1 = 4n(n − 1)/2 = 2n(n − 1).

- Ocenjeni broj operacija zaista se dobija kad su elementi početnog niza sortirani silazno.
- S druge strane, ako je početniniz već sortirano uzlazno, obaviće se samo jedan prolaz s
n−1upoređivanja i 0 zamena.

8
- Za bilo koje drugo uredenje početnog polja broj operacija je izmedu (n − 1) i 2n(n − 1).
- U svakom slučaju, vreme izvodenja je O(n2).

5. Sortiranje korišćenjem drveta (heap sort)

Heap sort je postupak sortiranje korišćenjem binarnog drveta. Elementi niza se ubacuju na
odgovarajuće pozicije tako da grade heap, specificno binarno stablo koje zadovoljava sledeće
osobine:

a) Nivoi stabla se popunjavaju redom, da bi prešli na sledeći nivo moramo prethodni popuniti
do kraja. Svi čvorovi, osim čvorova na pretposlednjem nivou imaju dva naslednika.
Određeni broj krajnje levih čvorova pretposlednjeg nivoa ima oba naslednika, zatim jedan
čvor može imati smao jednog levog naslednika, a preostali čvorovi nemaju nalsednika.

b) Svakom čvoru je pridružena vrednost iz niza koji sortiramo, i pri tome je vrednost koja je
pridružena proizvoljnom čvoru veća ili jednaka od vrednosti pridružene njegovim potomcima. Iz
toga proizilazi da ce se u korenu uvek nalaziti maksimalni član niza.

Svako drvo koje zadovoljava prvo svojstvo a) lako se predstavlja jednodimenzionim


nizom. Vrednost pridružena korenu se zapisuje u nultom članu niza (a[0]). Ako je vrednost
pridružena nekom čvoru zapisana u elementu a[i], onda je vrednost pridružena njegovom levom
nasledniku a[2*i+1] a desnom a[2*i+2]. Vrlo lako se računa i obrnuto, tj. ako je nekom čvoru
pridružena vrednost a[i] onda je roditelju tog čvora pridružena vrednost a[(i-1)/2].

Za predstavljanje heap-a u toku sortiranja koristi se niz koji se sortira. Polazimo od toga
da heap sadrži jedan element a[0], a zatim mu redom dodajemo elemente a[i] za i=1,2,...,n-1. Pri
dodavanju i-tog elementa u heap, elementi od 0-tog do (i-1)-og predstavljaju heap. Da bi osobina
b) bila ispunjena pri građenju heapa element niza koji postavljamo a[i] moramo "gurati gore"
(moramo ga menjati sa čvorom "roditeljom" ) sve dok ne bude manji od "roditeljskog" elementa
ili dok ne postane koren. Ako je element veći od roditeljskog elementa razmenimo ih, i
nastavljamo proveru za roditeljski čvor. Zato koristimo promenljivu j koju na početku
inicijalizujemo na i. Dok je a[j] veći od roditeljskog elementa a[(j-1)/2]), razmenimo njihove
vrednosti i j postaje roditeljski čvor(j=(j-1)/2;).

Formiranje heapa realizovano je metodom "napraviHeap".

void napraviHeap1(int[] a, int n)


{

9
int i, j;
for (i = 1; i < n; i++)
{
j = i;
while (j > 0 && a[j] > a[(j - 1) / 2])
{
razmeni(ref a[j], ref a[(j - 1) / 2]);
j = (j - 1) / 2;
}
}
}

Kada je heap formiran sortiranje izvršavamo određivanjem jednog po jednog elementa


sortiranog niza i njegovo uzimanje iz heap-a. Elemente određujemo redom od poslednjeg
elementa do prvog. Na poslednejm mestu u sortiranom nizu stajaće najveći element. Najveći
element nalazi se u korenu heap-a (a[0]), on se razmenjuje sa poslednjim elementom, na taj
način smo smanjili heap za jedan element, a u sortiranom nizu dodali jedan element na pravo
mesto. Međutim sada binarno stablo koje sadrži redom elemente a[0], a[1], .., a[n-2], mora da se
transformise da bi i zadovoljavao osobinu b), tj da bi bio heap. U heap-u je došlo do promene
vrednosti u korenu, u korenu mora da se nalazi najveća vrednost. Kako je pre transformacije niz
prestavljao heap, najveća vrednost levog podrveta nalazi se u levom potomku korena, a desnog
poddrveta u desnom potomku. U korenu heapa treba staviti najveću vrednost od tri vrednosti:
korena, levog potomka i desnog potomka. Ako najveća vrednost nije u korenu, čvor koji je u
korenu razmenjuje vrednost sa čvorom koji sadrži najveću vrednost. Na taj način čvor u kojem je
prešla vrednost iz korena ne mora zadovoljavati svojstvo b) pa se postupak ponavlja za taj čvor
sve dok se vrednost koja je na početku bila u korenu kreće (propada) kroz drvo, tj. dok postoji
naslednik sa većom vrednošću. U svakom koraku odredi se najveća vrednost od a[i], a[2*i+1] i
a[2*i+2] i njen indeks se zapamti u max. Ako je i==max kraj, inače a[i] se razmeni sa a[max] i
postupak se ponavlja za stablo čiji je koren max.

Kreiranje sortiranog niza od heap-a je realizovano metodom "izHeapaUSort".

void izHeapaUSort(int[] a, int n)


{
for (int i = n - 1; i >= 0; i--)
{
razmeni(ref a[0], ref a[i]);
goDown(a, i, 0);
}
}

10
Kretanje (Propadanje) i-tog elementa u nizu a dužine n koji predstavlja heap,
realaizovano je metodom „goDown“.

void goDown(int[] a, int n, int i)


{
int l, d, max;
bool kraj = false;
while (!kraj)
{

l = 2 * i + 1;
d = 2 * i + 2;
max = i;
if (l < n && a[l] > a[max])
max = l;
if (d < n && a[d] > a[max])
max = d;
if (max != i)
{
razmeni(ref a[max], ref a[i]);
i = max;
}
else kraj = true;
}
}

void heapSort(int[] a, int n)


{
// pravljenje heapa
napraviHeap1(a, n);
// formiranje sortiranog niza koriscenjem heapa
izHeapaUSort(a, n);
}

Drugi način za pravljenje heapa:

Druga polovina niza a[n/2],..., a[n-1] su listovi, pa svaki od njih možemo shvatiti kao
jednočlani heap. Preostale članove niza dodajemo redom a[n/2-1],..., a[1], a[0], kao što se vrši
transformacija heapa posle razmene a[i] i a[0], da zadovoljava svojstvo b) u funkciji
izHeapaUSort, na taj način dva postojeća heapa spajamo u jedan heap. Nakon dodavanja svih
elemenata ostaje jedan heap.

void napraviHeap2(int[] a, int n)

11
{
for (int i = n/2-1;i>=0;i--)
goDown(a, n, i);
}

Sledi analiza složenosti algoritma sortiranja pomoću hrpe (heap sort).


- Algoritam se svodi nan-struku primenu operacije ubacivanja elementa u gomilu,
odnosno izbacivanjanajmanjeg elementa iz gomile.
- Budući da jedno ubacivanje odnosno izbacivanje ima složenost O(log n), sledi da je
vrijeme unajgorem slučaju za celo sortiranje reda O(n log n).
- Eksperimenti pokazuju da heap-sort zaista spada medu najbrže poznate algoritme za
sortiranjei da uspešno sortira vrlo velika polja.

12
6. Literatura

www.google.com

www.pcpress.co.rs/index.asp

www.specijalisticki.tzv.hr

www.mycity.rs/Opste-programiranje/Neki-poznatiji-algoritmi-objasnjenje-i-implementacije.html

www.elfak.ni.ac.rs

13

You might also like