offline
- N1k0l4
- Prijatelj foruma
- Pridružio: 06 Sep 2005
- Poruke: 3800
- Gde živiš: Beograd
|
Posle duze pauze, sledi nastavak, ubrzo nadam se i sledeci.
U planu su jos hes tabele
Mozda neki geometrijsi algoritmi
- utvrdjivanje da li je tacka unutar mnogougla
- konsturkcija mnogougla
- konveksni omotac
Algebarski algoritmi
- Stepenovanje (vise varijanti)
- Mnozenje matrica (vise varijanti )
- Mnozenje polinoma
Quick sort
Quick sort algoritam za sortiranje niza je jedan od najbrzih algoritama koji danas postoji. Selection sorti i bubble sort koji su gore opisani imaju vreme izvrsavanja O(n^2) (O slozenosti imate link u 4. redu prvog posta u ovoj temi) , dok quick sort ima slozenost O(n log(n))
Ideja algoritma:
- Izaberi jedan clan niza, koji cemo zvati pivot
- Uredi niz tako da svi clanovi koji su manji od pivota budu sa leve strane a svi veci sa desne strane pivota.
- Rekurzivno uradi za levi odnosno desni podniz (u odnosu na pivota)
SLIKA:
Kao sto rekoh, quick sort je jedan od najbrzih algoritama za sortiranje koji su zasnovani na poredjenju (postoje algoritmi za sortiranje koji se ne zasnivaju na poredjenju elemenata, bice kasnije objasnjeni) , ali ukoliko se lose izabere pivot moze se desiti da mu vreme izvrsavanja bude kvadratno, tj. O(n^2) . To je slucaj kada je niz vec sortiran (ukoliko se za pivota uzima prvi clan niza)
Merge sort
Merge sort je algoritam cija je slozenost kao i kod quick sort-a, dakle O(n log(n)) . Ideja je sledeca:
- Ukoliko imamo niz duzine 1 , on je vec sortiran, u suprotnom:
- Podeli niz u dva podniza na pola (ili priblizno pola )
- Rekurzivno sortiraj oba podniza
- Spoj dva sortiraja podniza u jedan
Slika koja prilicno dobro opisuje algoritam :
Pseudo kod (preuzeto sa : wikipedije)
function merge_sort(m)
if length(m) ≤ 1
return m
var list left, right, result
var integer middle = length(m) / 2
for each x in m up to middle
add x to left
for each x in m after middle
add x to right
left = merge_sort(left)
right = merge_sort(right)
if left.last_item > right.first_item
result = merge(left, right)
else
result = append(left, right)
return result
function merge(left,right)
var list result
while length(left) > 0 and length(right) > 0
if first(left) ≤ first(right)
append first(left) to result
left = rest(left)
else
append first(right) to result
right = rest(right)
end while
if length(left) > 0
append left to result
else
append right to result
return result
Kratak rezime algoritama za sortiranje
Ovde sam napisao cetiri algoritma za sortiranje (selection sort, bubble sort, quick sort, merge sort ). Koji koristiti? -Zavisi od potrebe. Selection sort i bubble sort su mnogo jednostavniji za implementaciju, za shvatanje, intuitivniji su, ali su sporiji. Ipak, ukoliko znamo da niz nece imati veliki broj clanova, ne treba se muciti i implementirati quick sort ili merge sort, jer korisnik nece primetiti razliku u izvrsavanju.
Na adresi:
http://www.sorting-algorithms.com/
Klikom na neku od slicica videcete animaciju brzine kako radi algoritam. Veoma dobro odradjeno imate nekoliko vrsta nizova koje sortiraju pa mozete pogledati.
Na adresi
http://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms
Imate tabelu prednosti i mana algoritama za sortiranje
Sledeca tema: Strukture podataka
Vektor
Vektor (niz) je niz elemenata istog tipa. Velicina vektora je broj elemenata u nizu i ona je fiksirana (moramo unapred znati koliki je niz u koji smestamo neke podatke). Prednost ove strukture je sto nam ako znamo da se prvi element nalazi na poziciji x, a velicina jednog podaka je k bajtova, onda je n-ti element u nizu na poziciji x+(m-1)k sto nam omogucava jednostavno pristupanje bilo kom elementu za vreme O(1).
Nedostatak ove strukture je sto su mu svi podaci istog tipa i sto se ne moze prosirivati u vreme izvrsavanja programa(nije dinamicki). Ipak, i pored toga u mnogim trenutcima ce biti moguce njegovo koriscenje i treba ga koristiti kad god je to moguce.
Povezana lista
Povezana lista je jedna od dinamickih struktura podataka. Nije neophodno znati koliko ce prostora u memoriji zauzimati, i moze se menjati njena velicina za vreme izvrsavanja programa. Ideja povezane liste je da se podaci zapisuju nezavisno, a da opet budu nekako povezani, tj. povezani preko pokazivaca. Dakle, svaki clan povezane liste ima dva polja: vrednost i pokazivac na sledeci element . Prolazak kroz listu je moguc jedino linearno, odnosno, ako trazimo neki element na k-toj poziciji, mi moramo proci kroz k-1 clanova liste da bi smo dosli do njega, jer ne znamo gde se on tacno nalazi u memoriji. Mana ove strukture je sto zauzima nesto vise prostora u memoriji ( zbog pokazivaca), sporije pristupanje k-tom elementu, ali prednosti su brze upisivanje i brisanje u/iz liste.
Ideja kod ubacivanja novog elementa:
- Nadji poziciju gde treba ubaciti novi element
- Pokazivac njegovog prethodnika kopirati u polje pokazivaca novog podatka, a zatim ga promeniti da pokazuje na novi podatak.
Brisanje ima slicnu ideju (menjanje pokazivaca)
Stabla
Uvod
Stablo je hijerarhijska struktura.
Korensko stablo je skup cvorova i grana koje povezuju cvorove. Jedan cvor je izdvojen, i on je u vrhu, naziva se koren. Svaki cvor osim koren ima svog "oca". U stablu nema ciklusa, jer izmedju svaka dva cvora postoji jedinstven put. Cvor moze da ima "potomke" odnosno "sinove". Dakle, cvorovi koji izlaze iz nekog cvora su njegovi sinovi. Ukoliko cvor nema sinove onda se on zove "list". Maksimalan broj sinova je stepen stabla.
Binarno stablo (o kojem cemo najvise ovde pricati) je stablo ciji je maksimalan stepen dva.
Moguca su dva nacina predstavljanja stabla : implicitno(preko niza) i eksplicitno(preko pokazivaca) .
Binarno stablo pretrage
Kod binarnog stabla, svaki cvor moze imati najvise dva sina(levi i desni). Karakteristika BSP-a je da je svaki cvor veci od svih potomaka u levom podstablu, a manji od svih potomaka u desnom(po dogovoru, jednake mozemo smestati ili u levo ili desno podstablo)
Da ne pricam u prazno, vizuelni prikaz za pocetak:
Operacije kod binarnog stabla:
- Pronalazenje kljuca
- Ubacivanje kljuca
- Brisanje kljuca
Nalazenje:
Ideja je jednsotavna. Krenemo od korena, ukoliko je koren veci od traznog kljuca idemo u levo podstablo, u suprotom u desno. Ponavljamo postupak sve dok ne nadjemo kljuc ili ne naidjemo na NULL (pokazivac na NULL znaci da ne postoji sledeci element, odnosno da nema potomka)
Slicna ideja je i za ubacivanja novog kljuca.
Brisanje kljuca je nesto komplikovanije. Postoji vise slucajeva. Najjednostavnije je brisanje lista, jednostavno sklonimo pokazivac njegovog oca, odnosno postavimo ga na NULL. Drugi slucaj je uklanjanje cvora sa jednim sinom. Takodje, nista tesko, pokazivac od oca cvora koji se brise usmerimo na sina cvora. Ukliko cvor ima oba podstabla , brisanje ide na sledeci nacin: Pronadjemo najlevlji kljuc u desnom podstablu, ili najdesnji u levom. Taj kljuc kopiramo u cvor koji treba izbrisati, a njega brisemo(brisanje lista je trivijalno , prvi slucaj gore)
Sto se tice slozenosti operacija, zavisi od visine stabla, odnosno da li je stablo uravnotezeno ili ne. U najgorem slucaju, slozenost je proporcionalna visini stabla, a ako je uravnotezen, onda je njegova visina log2(n) pa se sve te operacije efikasno izvrsavaju.
AVL stabla
U prethodnom delu videli smo sta su stabla i sta su binarna stabla. Ovde sada pricamo o AVL stablima. AVL stablo je stablo gde se garantuje da slozenost bilo koje od operacija brisanje, ubacivanje novog, trazenje cvora biti u najgorem slucaju O(n log(n)). Zasto je tako? - Zato sto je ideja AVL stabla da se posle svake operacije stablo uravnotezi, tako da mu je visina uvek O(log n) . Poenta je u tome da razlika visina izmedju levog i desnog podstabla svakog cvora bude -1, 0, 1 . Cvor kod kojeg razlika levog i desnog podstabla nije -1,0 ili 1 naziva se kriticni cvor i oko njega se vrse rotacije da bi se uravnotezio.
Postoji vise slucajeva da se pojavi neuravnotezeno AVL stablo.
1) Levo-levo (ako je levo podstablo imalo vecu visinu od desnog i ako je novi cvor ubacen u levo) , slicno i za ostale.
2) Desno-desno
3) Levo-desno
4) Desno-levo
slika koja opisuje rotacije:
|