АСП2/К3 2018 — разлика између измена
м (→Rešenje) |
м (Замена начина истицања милокода.) |
||
(Није приказана једна међуизмена другог корисника) | |||
Ред 35: | Ред 35: | ||
=== Rešenje === | === Rešenje === | ||
Prilikom umetanja tražimo prvu poziciju na kojoj je prazno mesto, prvo jednom a zatim i drugom heš funkcijom. Ako se desi da se vratimo na početnu poziciju, to znači da je tabela puna i ključ se ne može umetnuti. | Prilikom umetanja tražimo prvu poziciju na kojoj je prazno mesto, prvo jednom a zatim i drugom heš funkcijom. Ako se desi da se vratimo na početnu poziciju, to znači da je tabela puna i ključ se ne može umetnuti. | ||
< | {{Милокод|<nowiki> | ||
INSERT(table, K) | INSERT(table, K) | ||
adr1 = adr1_init = h1(K) | adr1 = adr1_init = h1(K) | ||
Ред 54: | Ред 54: | ||
until (adr1 = adr1_init) or (adr2 = adr2_init) | until (adr1 = adr1_init) or (adr2 = adr2_init) | ||
ERROR(Tabela je puna) | ERROR(Tabela je puna) | ||
</ | </nowiki>}} | ||
Pretraga je slična umetanju, s tim što ako naiđemo na neprazno polje prvo proveravamo da li to polje sadrži traženi ključ i nastavljamo pretragu ako ne sadrži. Pretraga se takođe završava ako su obe pretrage došle do praznog polja. | Pretraga je slična umetanju, s tim što ako naiđemo na neprazno polje prvo proveravamo da li to polje sadrži traženi ključ i nastavljamo pretragu ako ne sadrži. Pretraga se takođe završava ako su obe pretrage došle do praznog polja. | ||
< | {{Милокод|<nowiki> | ||
SEARCH(table, K) | SEARCH(table, K) | ||
adr1 = adr1_init = h1(K) | adr1 = adr1_init = h1(K) | ||
Ред 73: | Ред 73: | ||
until (adr1 = adr1_init) or (adr2 = adr2_init) or ((table[adr1] = empty) and (table[adr2] = empty)) | until (adr1 = adr1_init) or (adr2 = adr2_init) or ((table[adr1] = empty) and (table[adr2] = empty)) | ||
return false | return false | ||
</ | </nowiki>}} | ||
== 3. zadatak == | == 3. zadatak == | ||
Ред 121: | Ред 121: | ||
=== Rešenje === | === Rešenje === | ||
Kod ovog algoritma jeste najveći problem to što <code>n-1</code> puta radi iteraciju kroz niz, kada je to potrebno raditi samo dok se ne desi da nije bilo nijedne zamene u unutrašnjoj petlji. Drugi problem jeste nepotreban prolazak od kraja do početka niza, kada je prolazak od početka do kraja potencijalno efikasniji zbog keš memorije. Takođe, nije potrebno prolaziti kroz sortirani deo prilikom zamene elemenata. | Kod ovog algoritma jeste najveći problem to što <code>n-1</code> puta radi iteraciju kroz niz, kada je to potrebno raditi samo dok se ne desi da nije bilo nijedne zamene u unutrašnjoj petlji. Drugi problem jeste nepotreban prolazak od kraja do početka niza, kada je prolazak od početka do kraja potencijalno efikasniji zbog keš memorije. Takođe, nije potrebno prolaziti kroz sortirani deo prilikom zamene elemenata. | ||
< | {{Милокод|<nowiki> | ||
BUBBLE SORT REVISITED(arr, n) | BUBBLE SORT REVISITED(arr, n) | ||
pos = n | |||
repeat | repeat | ||
granica = pos | |||
broj_zamena = 0 | broj_zamena = 0 | ||
for | for i = 1 to granica - 1 do | ||
if arr[ | if arr[i] > arr[i+1] then | ||
arr[ | arr[i] ↔ arr[i+1] | ||
granica = i | |||
broj_zamena = broj_zamena + 1 | broj_zamena = broj_zamena + 1 | ||
end_if | end_if | ||
end_for | end_for | ||
until broj_zamena = 0 | until broj_zamena = 0 | ||
</ | </nowiki>}} | ||
== 5. zadatak == | == 5. zadatak == | ||
Ред 232: | Ред 233: | ||
* Ulančana lista je jednostruko ulančana, pa naknadno moramo dohvatati elemente liste koje sadrže stablo sa minimalnim korenom nakon pozivanja <code>findMin</code> | * Ulančana lista je jednostruko ulančana, pa naknadno moramo dohvatati elemente liste koje sadrže stablo sa minimalnim korenom nakon pozivanja <code>findMin</code> | ||
* Ulančana lista u hipu sadrži polje ''next'' koje pokazuje do sledećeg čvora ulančane liste i polje ''value'' koje pokazuje na ''BinTree'' objekat, i sve operacije kao što su se koristile na ASP1 su podržane | * Ulančana lista u hipu sadrži polje ''next'' koje pokazuje do sledećeg čvora ulančane liste i polje ''value'' koje pokazuje na ''BinTree'' objekat, i sve operacije kao što su se koristile na ASP1 su podržane | ||
< | {{Милокод|<nowiki> | ||
REMOVE MIN KEY(binheap) | REMOVE MIN KEY(binheap) | ||
first_node = binheap.getFirst() | first_node = binheap.getFirst() | ||
Ред 256: | Ред 257: | ||
FREETREE(min_tree) | FREETREE(min_tree) | ||
FREENODE(curr_node) | FREENODE(curr_node) | ||
</ | </nowiki>}} | ||
< | {{Милокод|<nowiki> | ||
INSERT TREE(binheap, bintree) | INSERT TREE(binheap, bintree) | ||
curr = binheap.getFirst() | curr = binheap.getFirst() | ||
Ред 280: | Ред 281: | ||
value(next(prev)) = bintree | value(next(prev)) = bintree | ||
next(next(prev)) = nil | next(next(prev)) = nil | ||
</ | </nowiki>}} | ||
== 7. zadatak == | == 7. zadatak == |
Тренутна верзија на датум 13. септембар 2024. у 01:09
Postavka zadataka na stranici predmeta.
1. zadatak
Postavka
Prikazati izgled binarnog hipa nakon uklanjanja minimalnog ključa i nakon umetanja ključeva 9 i 30.
5 / \ 10 7 / \ / \ 47 32 12 31 / 54
Rešenje
Nakon uklanjanja minimalnog ključa:
7 / \ 10 12 / \ / \ 47 32 54 31
Nakon umetanja ključeva 9 i 30:
7 / \ 9 12 / \ / \ 10 32 54 31 / \ 47 30
2. zadatak
Postavka
Napisati iterativnu implementaciju sledećeg algoritma heširanja. Za heširanje se koriste dve heš funkcije, h1(K) i h2(K), dok se za razrešavanje kolizija koristi sekundarna heš funkcija g(k). Nad ključem K koji se ubacuje u tabelu se primenjuju i funkcija h1(K) i h2(K), a kao ulaz se koristi rezultat funkcije za koju se dobije manje kolizija. U slučaju jednakog broja kolizija, koristi se funkcija h1(K). Potrebno je realizovati operacije umetanja i pretrage.
Rešenje
Prilikom umetanja tražimo prvu poziciju na kojoj je prazno mesto, prvo jednom a zatim i drugom heš funkcijom. Ako se desi da se vratimo na početnu poziciju, to znači da je tabela puna i ključ se ne može umetnuti.
INSERT(table, K) adr1 = adr1_init = h1(K) adr2 = adr2_init = h2(K) repeat if table[adr1] = empty then table[adr1] = K return else adr1 = (adr1 + g(K)) mod n end_if if table[adr2] = empty then table[adr2] = K return else adr2 = (adr2 + g(K)) mod n end_if until (adr1 = adr1_init) or (adr2 = adr2_init) ERROR(Tabela je puna)
Pretraga je slična umetanju, s tim što ako naiđemo na neprazno polje prvo proveravamo da li to polje sadrži traženi ključ i nastavljamo pretragu ako ne sadrži. Pretraga se takođe završava ako su obe pretrage došle do praznog polja.
SEARCH(table, K) adr1 = adr1_init = h1(K) adr2 = adr2_init = h2(K) repeat if table[adr1] = K then return true else if table[adr1] ≠ empty then adr1 = (adr1 + g(K)) mod n end_if if table[adr2] = K then return true else if table[adr2] ≠ empty then adr2 = (adr2 + g(K)) mod n end_if until (adr1 = adr1_init) or (adr2 = adr2_init) or ((table[adr1] = empty) and (table[adr2] = empty)) return false
3. zadatak
Postavka
Data je sekvenca ključeva: 169, 84, 99, 6, 61, 84, 9, 96, 158, 42, 495, 46, 223. Prikazati rad shell sort algoritma po koracima. Navesti korišćenu sekvencu inkremenata i obrazložiti izbor.
Rešenje
Inkrementi su izabrani kao u rešenju šestog zadatka sa trećeg kolokvijuma 2020. godine.
Inkrement | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Početak | 169 | 84 | 99 | 6 | 61 | 84 | 9 | 96 | 158 | 42 | 495 | 46 | 223 |
7 | 96 | 84 | 42 | 6 | 46 | 84 | 9 | 169 | 158 | 99 | 495 | 61 | 223 |
5 | 84 | 9 | 42 | 6 | 46 | 96 | 61 | 169 | 158 | 99 | 495 | 84 | 223 |
3 | 6 | 9 | 42 | 61 | 46 | 96 | 84 | 169 | 84 | 99 | 495 | 158 | 223 |
3 | 6 | 9 | 42 | 61 | 46 | 84 | 84 | 169 | 96 | 99 | 495 | 158 | 223 |
2 | 6 | 9 | 42 | 61 | 46 | 84 | 84 | 99 | 96 | 158 | 223 | 169 | 495 |
1 | 6 | 9 | 42 | 46 | 61 | 84 | 84 | 96 | 99 | 158 | 169 | 223 | 495 |
4. zadatak
Postavka
Priloženi pseudokod prikazuje jednu varijantu bubble sort algoritma za sortiranje podataka. Objasniti glavne nedostatke priloženog algoritma i napisati u pseudokodu alternativnu implementaciju ovog algoritma koja te nedostatke ispravlja.
for i:=1 to n-1 do for j:=n-1 downto 1 do if arr[j]>arr[j+1] then b:=arr[j]; arr[j]:=arr[j+1]; arr[j+1]:=b; end_if end_for end_for
Rešenje
Kod ovog algoritma jeste najveći problem to što n-1
puta radi iteraciju kroz niz, kada je to potrebno raditi samo dok se ne desi da nije bilo nijedne zamene u unutrašnjoj petlji. Drugi problem jeste nepotreban prolazak od kraja do početka niza, kada je prolazak od početka do kraja potencijalno efikasniji zbog keš memorije. Takođe, nije potrebno prolaziti kroz sortirani deo prilikom zamene elemenata.
BUBBLE SORT REVISITED(arr, n) pos = n repeat granica = pos broj_zamena = 0 for i = 1 to granica - 1 do if arr[i] > arr[i+1] then arr[i] ↔ arr[i+1] granica = i broj_zamena = broj_zamena + 1 end_if end_for until broj_zamena = 0
5. zadatak
Postavka
Podaci se smeštaju u heš tabelu sa 7 ulaza primenom heš funkcije hp(K) = K mod 7. Za razrešavanje kolizija se koristi metoda dvostrukog heširanja sa sekundarnom heš funkcijom hs(K) = 4 + K mod 3. Odrediti prosečan broj pristupa prilikom neuspešnog traženja i verovatnoću popunjavanja praznih ulaza, pod pretpostavkom da su svi ključevi jednako verovatni.
0 | 14 |
---|---|
1 | |
2 | 11 |
3 | 24 |
4 | 18 |
5 | |
6 | 13 |
Rešenje
0 | 1 | 2 |
---|---|---|
0 | 0 | 0 |
4 | 5 | 6 |
1 | 3 | 5 |
5 | 1 | 4 |
2 | 6 | 3 |
6 | 4 | 2 |
3 | 2 | 1 |
- Prosečan broj neuspešnih pristupa:
- Verovatnoća popunjavanja:
- 1:
- 5:
6. zadatak
Postavka
Napisati u pseudokodu funkciju za uklanjanje minimalnog ključa u binomnom hipu i njegovu naknadnu reorganizaciju. Nije potrebno sprovesti potencijalno spajanje stabala nakon uklanjanja čvora sa minimalnim ključem. Binomni hip predstavljen pomoću objekta klase BinHeap koja sadrži ulančanu listu objekata BinTree koji predstavljaju pojedinačna binomna stabla. Lista je uređena rastuće po stepenu stabla. Binomno stablo se sastoji od čvorova predstavljenih objektima klase BinNode. Funkcija kao argument prima objekat klase BinHeap. U nastavku je dat spisak metoda koje su na raspolaganju, njihove povratne vrednosti i klase objekata za koje ih treba pozvati.
Metoda | Povratna vrednost | Objekat klase |
---|---|---|
getFirst | pokazivač na početak liste šume binomnih stabala | BinHeap |
findMin | pokazivač na binomno stablo u čijem korenu je minimalni ključ | BinHeap |
getOrder | red stabla | BinTree |
setOrder | nema | BinTree |
getRoot | pokazivač na koren binomnog stabla | BinTree |
getNumOfChildren | broj potomaka čvora binomnog stabla | BinNode |
getChildAtPos(index) | pokazivač na čvor koji je potomak objekta BinNode na poziciji index | BinNode |
Rešenje
Sledeće pretpostavke su usvojene pri implementaciji:
getFirst
vraća promenljivu referencu na lvrednost do početka ulančane liste, kako bismo mogli da ažuriramo taj početakgetChildAtPos
isto vraća promenljivu referencu na lvrednost. Ovo je kako bismo decu trenutnog čvora mogli da postavimo na nil, kako ne bi bila uništena prilikom dealokacije stabla (pretpostavljamo da postoji funkcija FREETREE koja to radi, slično FREENODE)- Postoji funkcija GETTREE koja samo alocira stablo i kao koren postavlja svoj prvi argument
- Ulančana lista je jednostruko ulančana, pa naknadno moramo dohvatati elemente liste koje sadrže stablo sa minimalnim korenom nakon pozivanja
findMin
- Ulančana lista u hipu sadrži polje next koje pokazuje do sledećeg čvora ulančane liste i polje value koje pokazuje na BinTree objekat, i sve operacije kao što su se koristile na ASP1 su podržane
REMOVE MIN KEY(binheap) first_node = binheap.getFirst() if first_node = nil then return end_if min_tree = binheap.getMin() prev_node = nil curr_node = first_node while value(curr_node) ≠ min_tree do prev_node = curr_node curr_node = next(curr_node) end_while next(prev_node) = next(curr_node) root = min_tree.getRoot() for i = 1 to root.getNumOfChildren() do child = root.getChildAtPos(i) tree = GETTREE(child) tree.setOrder(child.getNumOfChildren()) INSERT_TREE(binheap, tree) root.getChildAtPos(i) = nil end_for FREETREE(min_tree) FREENODE(curr_node) INSERT TREE(binheap, bintree) curr = binheap.getFirst() prev = nil while curr ≠ nil do if value(curr).getOrder() ≥ bintree.getOrder() then if prev = nil then binheap.getFirst() = GETNODE value(binheap.getFirst()) = bintree next(binheap.getFirst()) = curr else next(prev) = GETNODE value(next(prev)) = bintree next(next(prev)) = curr end_if return end_if prev = curr curr = next(curr) end_while next(prev) = GETNODE value(next(prev)) = bintree next(next(prev)) = nil
7. zadatak
Postavka
Podaci se smeštaju u heš tabelu sa 8 ulaza primenom heš funkcije po metodu deljenja. Za razrešavanje kolizija se koristi metoda slučajnog pretraživanja (c = 3). Prikazati proces razrešavanja kolizije i generisati ispitne nizove za ključeve 21 i 18. Objasniti da li kod ovog metoda u opštem slučaju dolazi do primarnog i sekundarnog grupisanja i zašto.
Rešenje
Pošto se koristi metoda slučajnog pretraživanja, moramo generisati slučajni niz za generisanje ispitnog niza:
011 = 3 *2 110 = 6 *2 1100 -8 100 ⊕3 111 = 7 *2 1110 -8 110 ⊕3 101 = 5 *2 1010 -8 010 ⊕3 001 = 1 *2 010 = 2 *2 100 = 4 *2 1000 -8 000 ⊕3 011 ...
21 | 18 |
---|---|
5 | 2 |
0 | 5 |
3 | 0 |
4 | 1 |
2 | 7 |
6 | 3 |
7 | 4 |
1 | 6 |
Proces razrešavanja kolizije:
- 21 % 8 = 5
- Ako je ulaz 5 zauzet: (5 + 3) % 8 = 0
- Ako je ulaz 0 zauzet: (5 + 6) % 8 = 3
- itd.
U opštem slučaju neće doći do primarnog grupisanja jer je sekvenca ključeva u ispitnom nizu nasumična a ne linearna, ali će doći do sekundarnog grupisanja jer ispitni niz zavisi samo od matične adrese i rednog broja pokušaja.
8. zadatak
Postavka
Precizno objasniti kako se dolazi do složenosti algoritama za sortiranje a) kvadratnom selekcijom b) stablom selekcije i c) spajanjem. U kojem od ovih algoritama se razlikuju najbolji, srednji i najgori slučaj složenosti.