You are on page 1of 9

SPA – (teorija sa radionice)

Tip podatka je opisan skupom mogucih vrednosti i operacija nad njima.

Tip podatka moze biti:


1. prost(int, char, double, float, decimal, boolean)
2. slozen(definisan preko prostih i drugih slozenih tipova podataka): primer. String definisan kao
char[] ili Student koji ima string ime, prezime i int godiste

Slozen tip podatka je struktura podataka.

Tipovi podataka se dele i na:


1. predefinisane(one koji postoje u programskom jeziku): prosti, String, niz itd...
2. korisnicki definisani(Student, CvorDSListe, DSLista...) kreiramo ih kroz koncept klasa,
struktura...

Tipovi mogu biti nullable(mogu imati null vrednost) i not nullable.

Podela na:
1. linearne(nizovi, liste)
2. nelinearne(stabla, grafovi, mreze)

Strukture podataka u zavisnosti od broja prethodnika i sledbenika:


Naziv(br prethodnika : br sledbenika)

1. Kolekcije i skupovi(0:0) - nemaju prethodnike niti sledbenike, ne postoji uredjenje izmedju


elemenata. Skupovi ne mogu sadrzati dva ista elementa dok kolekcije mogu.
2. Linearne strukture(niz, lista, red, stack) (1 : 1) - imaju najvise jednog prethodnika i najvise
jednog sledbenika
3. Stabla(1 : M) - najvise jedan prethodnik i M sledbenika
4. Grafovi i Mreze(M : M) - mogu da imaju M prethodnika i M sledbenika

Asimptotska kompleksonst algoritma

Dve vrste:
1. Vremenska
2. Prostorna(memorijska)

Nas interesuje samo vremenska posto je memorija resurs kojeg u danasnjim racunarima ima dovoljno.

Vremenska kompleksnost - predstavlja zavisno na osnovu koje se moze ocekivati povecanje vremena
izvrsenja algoritma u zavisnosti od povecanja ulaza.

Sta znaci O(n) - vreme potrebno za izvrsavanje algoritma raste proporcionalno sa velicinom ulaza(n)
Sta znaci O(1) - konstantno vreme izvrsavanja, ne zavisi od kolicine ulaza
n - velicina ulaza(npr kod niza br elemenata, kod stringa br karaktera...)
Ako na ulazu imamo niz velicina ulaza je broj elemenata niza, ako imamo string to je broj karaktera u
stringu ...

// Objasniti da konstante nisu bitne, i da one ne trebaju da se koriste u asimptotskoj kompleksnosti jer su
zanemarljive, posmatra ponasanje algoritma kada velicina ulaza neograniceno raste

zato je O(n) = O((1/2)*n)

O(1) < O (log2(log2(n)))< O(log2(n)) < O(n) < O(n*log2(n)) < O(n*(log2(n))^2) < O(n ^ 2) < O(2 ^ n)
< O(n!)

Sekvencijalna pretraga

static int sekvencijalo(int[] niz, int trazeni){


for(int i = 0; i < niz.length; i++)
if(niz[i] == trazeni)
return i;
return -1;
}

static int sekvencijalnoRek(int[] niz, int trazeni, int trenutni){


if(trenutni >= niz.length)
return -1;
if(niz[trenutni] == trazeni)
return trenutni;
return sekvencijalnoRek(niz, trazeni, trenutni+1);
}

Dobre strane: primenjiva na sve linijske strukture podataka(niz, lista), ne zahteva da budu sortirane
Lose strane: O(n) kompleksnost

Binarna pretraga rekurzivno

static int binary(int[] niz, int trazeni, int levi, int desni){
if(levi > desni) return -1;
int mid = (levi + desni) /2;
if(niz[mid] == trazeni)
return mid;
if(niz[mid] > trazeni)
return binary(niz,trazeni,levi, mid - 1);
return binary(niz,trazeni,mid+1, desni);
}
Binarna pretraga iterativno

static int binaryIter(int[] niz, int trazeni){


int levi = 0, desni = niz.length - 1;
int srednji;
while(levi <= desni){
srednji = (levi + desni) / 2;
if(niz[srednji] == trazeni)
return srednji;
if(niz[srednji] < trazeni)
levi = srednji + 1;
else
desni = srednji - 1;
}
return -1;
}

Dobre strane: Garantuje O(log2(n)) kompleksnost


Lose strane: Primenjivo iskljucivo na sortirane nizove

Interpolaciono pretrazivanje

(Pk - Pmin) / (Pmax - Pmin) = (K - MIN)/(MAX - MIN)


=> Pk = Pmin + (K - MIN) / (MAX - MIN) *(Pmax - Pmin)

static int interpolaciono(int[] niz, int trazeni){


int levi = 0;
int desni = niz.length - 1;
while (levi <= desni){
if(niz[desni] == niz[levi]){
if(niz[levi] == trazeni)
return levi;
return -1;
}
int index = levi + (trazeni - niz[levi]) / (niz[desni] - niz[levi]) * (desni - levi);
if(niz[index] == trazeni)
return index;
if(niz[index] > trazeni)
desni = index - 1;
else
levi = index + 1;
}
return -1;
}

static int interpolacionoRe(int[] niz, int trazeni, int levi, int desni){
if(levi > desni) return -1;
if(niz[levi] == niz[desni]){
if(niz[levi] == trazeni)
return levi;
return -1;
}
int index = levi + (trazeni - niz[levi]) / (niz[desni] - niz[levi]) * (desni - levi);
if(niz[index] == trazeni)
return index;
if(niz[index] > trazeni)
return interpolacionoRe(niz,trazeni,levi, index - 1);
return interpolacionoRe(niz,trazeni,index + 1,desni);

Prednosti: teoretski najveca efikasnost(najmanja kompleksnost) O(log2(log2(n)))


Nedostaci: u najgorem slucaju se degenerise u sekvencijalno pa je kompleksnost(O(n)), zahteva sortiran
niz

Selection sort

Prolazak kroz nesortirani deo i pronalaženje najmanjeg(najvećeg) elementa i njegovo postavljanje na


potrebno mesto

Efikasnost O(n^2)
Prikazati na tabli kako radi
7,3,1,4,2 => 1,3,7,4,2 => 1,2,7,4,3 => 1,2,3,4,7

static void selectionSort(int[] niz){


int min, temp;
for(int i = 0; i < niz.length - 1; i++){
min = i;
for(int j = i + 1; j < niz.length; j++){
if(niz[j] < niz[min])
min = j;
}
temp = niz[min];
niz[min] = niz[i];
niz[i] = temp;
}
}

Bubble sort

Počinje od kraja niza i zamenjuje susedne elemente, tako da najmanji element izađe na početak,
poredi medjusobno susedne elemente
Efikasnost O(n^2)

Nacrtati na tabli
2,5,4,3,1 => 2,5,4,1,3 = > 2, 5, 1, 4, 3 => 2, 1, 5 ,4, 3 => 1,2,5,4,3 => 1, 2, 5, 3, 4 =>
1,2,3,5,4 => 1, 2, 3, 4, 5

static void bubbleSort(int[] niz){


int temp;
for(int i = 0; i < niz.length - 1; i++) {
for (int j = niz.length-1; j > i; j--) {
if (niz[j - 1] > niz[j]) {
temp = niz[j - 1];
niz[j - 1] = niz[j];
niz[j] = temp;
}
}
}
}

Sink sort

Veoma slicno sto i bubble, samo sto krece od pocetka nalazi najveci element i postavlja ga na kraj,
poredi medjusobno susedne elemente
Efikasnost O(n^2)

static void sinkSort(int[] niz){


int temp;
for(int i = 0; i < niz.length - 1; i++){
for(int j = 0; j < niz.length - 1 - i;j++){
if(niz[j] > niz[j + 1]){
temp = niz[j];
niz[j] = niz[j+1];
niz[j+1] = temp;
}
}
}
}

Insetrion sort

Prolazak kroz nesortirani deo niza i ubacivanje sledeceg elementa u sortirani deo.

Efikasnost O(n^2)

8,2,4,8,5,6 => 2,8,4,9,5,6 => 2,4,8,9,5,6 => 2,4,8,9,5,6 => 2,4,5,8,9,6 => 2,4,5,6,8,9

static void insertionSort(int[] niz){


int trenutni;
for(int i = 0; i < niz.length; i++){
trenutni = niz[i];
int j = i;
while (j > 0 && niz[j - 1] > trenutni){
niz[j] = niz[j - 1];
j--;

}
niz[j] = trenutni;
}
}

Merge sort

Deli niz na dva podniza i tako rekurzivno dok ne ostane po samo jedan element, zatim se vraca unazad i
spaja podnizove(na pocetku samo po jedan element) dok ne sastavi pocetni niz u sortiranom redosledu.

Efikasnost: O(n*log2(n))
Prvo ih rastavlja
48753291

4875 3291

48 75 32 91

4 8 7 5 3 2 9
1

Pa onda krece da ih ststavlja u rastucem redosledu

48 57 23 19

4578 1239

12345789

Za merge ne treba objasnjavati kod, ko hoce da pogleda nek pogleda, pa nek pita ako ima nesto
nejasno

public static void mergeSort(int [] niz, int p,int k){


if(p<k){
int q = (p+k)/2;
mergeSort(niz, p, q);
mergeSort(niz, q+1, k);
merge(niz,p,q,k);
}
}

public static void merge(int [] niz, int p,int q,int k){


int n1 = q-p+1;
int n2 = k-q;
int [] levi = new int [n1];
int [] desni = new int [n2];

for(int i=0;i<n1;i++){
levi[i]=niz[p+i];
}

for(int j=0;j<n2;j++){
desni[j]=niz[q+1+j];
}
int i=0,j=0, m=p;
while(i<levi.length && j<desni.length){
if(levi[i]<=desni[j]){
niz[m]=levi[i];
m++;
i++;
}else{
niz[m]= desni[j];
m++;
j++;
}
}

while(i<levi.length){
niz[m]=levi[i];
m++;
i++;
}

while(j<desni.length){
niz[m] = desni[j];
m++;
j++;
}
}

Quick sort

Sortiranje zasnovano na pivotu za koga se uzima poslednji element niza, ideja je da na kraju svakog
prolaska niz bude podeljen u dva dela levo od pivota da budu elementi manji od njega, a desno da budu
veci.

Prosecna efikasnost O(n*log(n))


Najgora efikasnost O(n ^ 2)

Koristi se zato sto je u prosecnom slucaju najbrzi od svih O(n*log(n)), a najgori slucaj se desava samo ako
je niz vec sortiran.
Levi index krece od prvog elementa i nastavlja dok ne dodje do veceg ili jednakog pivotu.
Desni index krece od predposlednjeg elementa i nastavlja dok ne nadje prvi manji od pivota.
Kada je levi na prvom koji je veci ili jednak a desni na prvom koji je manji ta dva elementa menjaju mesta
i to se ponavlja dok u levom delu niza ne budu manji a u densom veci elementi.

Kada se to zavrsi element na kome su se zaustavili i levi i desni idex(na prvoj poziciji od pocetka niza koji
je veci od pivota) pivot i taj element menjaju mesta.

Zatim se postupak ponavlja rekurzivno za delove niza koji su levo i desno od pivota.

5, 23, 7, 9, 8, 15, 14, 3, 15, 11


. .

5, 3, 7, 9, 8, 15, 14, 23, 15, 11


..

5, 3, 7, 9, 8, 11, 14, 23, 15, 15

Pa se rekurzivno primenjuje na podniz 5, 3, 7, 9, 8 i podniz 14, 23, 15, 15

static void quickSort(int[] niz, int levi, int desni){


if(levi >= desni) return;
int i = partition(niz, levi, desni);
quickSort(niz, levi, i - 1);
quickSort(niz, i + 1, desni);
}

static int partition(int[] niz, int levi, int desni){


int pivot = niz[desni];
int i = levi - 1;
int j = desni;
while (true){
while (niz[++i] < pivot);
while (pivot < niz[--j])
if(j == i)
break;
if(i >= j) break;
int temp = niz[i];
niz[i] = niz[j];
niz[j] = temp;
}
int temp = niz[i];
niz[i] = niz[desni];
niz[desni] = temp;
return i;
}
Ako je posle iteracije quick sorta za neki pivot, dobijen niz
5 4 1 7 9 10 8, pronaci koji je pivot bio
5 4 1 7 8 9 10, znaci pivot je 7

Shell sort

Prosle godine nije bilo potrebno uciti, provericu sa Milosem


Potrebno je samo da se zna da je efikasnost O(n*((log2(n))^2))

Lista

Linearna struktura u koju se na bilo koje mesto moze ubaciti ili izbaciti element.

Prednosti u odnosu na niz : teoretski moze neograniceno da raste broj elemenata, lakse ubacivanje
elementa u sortiranu listu nego u niz(u nizu moramo da pomerimo sve elemente nakon mesta na kom je
novi element ubacen, za listu je potrebno samo da se napravi novi cvor i da se prevezu pokazivaci)

Nedostaci u odnosu na niz: manja efikasnost pretrazivanja, ne moze se implementirati algoritam brzi od
O(n), bez obzira da li je lista sortirana ili ne(vazi i za dvostruko i za jednostruko spregnutu listu), pa se iz
tog razloga za liste koristi obicna sekvencijalna pretraga.

sta ispisuje sledeci kod:


int a = 0;
syso(++a);
syso(a--);
syso(++a);
ispis: 1 1 1

int a = 5;
int b = a--;
a = b++ + --a;
syso(--b);
syso(a++);
//ispisuje 5 8

Ciklicna DS lista sa cetiri cvora, pom na jednom, sta je rezultat izvrsavanja koda:
pom.sledeci.prethodni.prethodni = pom.sledeci.sledeci;
pom = pom.prethodni.prethodni;
pom.sledeci.sledeci = pom.prethodni;

You might also like