ASP auditorne vježbe 4 Liste i redovi; pokazivači na pokazivače; obilazak stabla.

Download Report

Transcript ASP auditorne vježbe 4 Liste i redovi; pokazivači na pokazivače; obilazak stabla.

ASP auditorne vježbe 4
Liste i redovi; pokazivači na
pokazivače; obilazak stabla
1
Creative Commons
•
slobodno smijete:
– dijeliti — umnožavati, distribuirati i javnosti priopćavati djelo
– remiksirati — prerađivati djelo
•
pod sljedećim uvjetima:
– imenovanje. Morate priznati i označiti autorstvo djela na način kako je
specificirao autor ili davatelj licence (ali ne način koji bi sugerirao da Vi
ili Vaše korištenje njegova djela imate njegovu izravnu podršku).
– nekomercijalno. Ovo djelo ne smijete koristiti u komercijalne svrhe.
– dijeli pod istim uvjetima. Ako ovo djelo izmijenite, preoblikujete ili
stvarate koristeći ga, preradu možete distribuirati samo pod licencom
koja je ista ili slična ovoj.
U slučaju daljnjeg korištenja ili distribuiranja morate drugima jasno dati do znanja licencne uvjete
ovog djela. Najbolji način da to učinite je linkom na ovu internetsku stranicu.
Od svakog od gornjih uvjeta moguće je odstupiti, ako dobijete dopuštenje nositelja autorskog
prava.
Ništa u ovoj licenci ne narušava ili ograničava autorova moralna prava.
Dijelovi ove prezentacije preuzeti su iz pratećih materijala predavanja FER-a Sveučilišta u
Zagrebu
Tekst licencije preuzet je s http://creativecommons.org/.
2
Zadatak 1 (ZI 2012)
Za red realiziran jednostruko povezanom listom napišite funkciju dodaj za
dodavanje elementa u red.
Prototip funkcije je:
int dodaj(int element, atom **ulaz, atom **izlaz);
Funkcija treba vratiti 1 ukoliko je element uspješno dodan u red, a 0 inače.
Tip atom definiran je sljedećim programskim odsječkom:
struct at {
int element;
struct at *sljed;
};
typedef struct at atom;
3
Dodavanje elementa u red realiziran listom
int DodajURed (int element, Red *red) {
atom *novi;
if (novi = malloc (sizeof (atom))) {
novi->element = element;
novi->sljed = NULL;
if (red->izlaz == NULL) red->izlaz = novi; //ako je bio prazan
else (red->ulaz)->sljed = novi;
// inace, na kraj
red->ulaz = novi;
// zapamti zadnjeg
return 1;
}
novi
return 0;
}
red->ulaz
red->izlaz
Pozivni program:
Red red;
init_red(&red);
DodajURed(52,
&red);
52
4
Realizacija reda listom


problem kod realizacije poljem jest mogućnost popunjenja
u stvarnosti veličina reda nije ograničena

realnija je realizacija listom
typedef struct at atom;
struct at {
int element;
struct at *sljed;
};
typedef struct {
atom *ulaz, *izlaz;
} Red;
atom
atom
element
sljed
5
Usporedba s primjerom iz predavanja
A: int DodajURed (int element, Red *red);
B: int dodaj(int element, atom **ulaz, atom **izlaz);
Razlike? Zašto?
Informacija je ista – u (A) smo dva pokazivača
„zapakirali” u strukturu Red
Pored toga, strukturom možemo doći do adrese
pokazivača, red->izlaz u (A) je slično kao *izlaz u (B)
6
Strategija rješavanja
• Ulazom u funkciju imamo integer, trebamo ga
dodati u red  očito prvo kreiramo zapis
• U postojeći red dodajemo novi zapis na ulaz
(„kraj” reda)
• Pokazivač na kraj reda moramo pomaknuti na
novi kraj  ako je ulaz adresa pokazivača kraja
onda sa *ulaz na LHS (left-hand side, lijevo od
znaka „=”) pokazivač na zapis
• Na kraju rubni uvjeti
7
Zadatak 2 (ZI 2008.)
U jednostruko povezanu listu spremaju se podaci o
radnicima nekog poduzeća. Lista je zadana sljedećim
strukturama.
struct zapis {
char imeprezime[30+1];
int matbr;
int godisnji;
};
struct at {
struct zapis element;
struct at *sljed;
};
typedef struct at atom;
8
Zadatak 2 nastavak
Jedan element liste sadrži sljedeće podatke: ime i prezime
radnika (30+1 znakova), matični broj radnika (int) i broj
dana godišnjeg odmora (int). Lista nije sortirana.
Napisati funkciju koja će iz liste izbaciti one radnike koji
imaju više od 30 dana godišnjeg odmora.
Funkcija mora imati prototip:
void izbaci(atom **glava);
9
Strategija rješavanja
• Negdje u main()-u je lista bila popunjena i u
main()-u se nalazi pokazivač „atom* adresaListe,
a sadrži adresu same liste, recimo „0x100“
• Ako je prvi element liste bio izvađen i stavljen u
novu listu, očito moramo u main()-u promijeniti
vrijednost u pokazivaču adresaListe. Zato funkciji
moramo predati adresu tog pokazivača (recimo
da je pokazivač na adresi „0xA”), tako da u
funkciji promijenimo sadržaj te lokacije
10
Strategija rješavanja (2)
• Kretati ćemo se po listi i izbacivati neke elemente
• Da bismo izbacili element, treba nam adresa
istog (pokazivač na struct)
• Da bismo povezali prethodnika na sljedbenika,
dovoljan nam je pokazivač (radimo standardnu
operaciju tipa
„kaskajuci = front; front = front -> slijedeci;”)
• Samo za glavu liste moramo imati pokazivač na
pokazivač – imamo varijablu glava iz argumenta!
11
Zadatak 3 (dekanski 2011.)
U jednostruko povezanu nesortiranu listu spremljeni su
podaci o uspjehu studenata na nekom predmetu. Lista je
zadana sljedećim strukturama:
struct zapis {
char imeprezime[80+1];
char jmbag[10];
float ocjena;
};
struct at {
struct zapis element;
struct at *sljed;
};
typedef struct at atom;
12
Zadatak 3 nastavak
Jedan element liste sadrži sljedeće podatke: ime i prezime
studenta (80+1 znakova), JMBAG (10 znakova) i završna
ocjena iz predmeta (float).
Napišite funkciju koja će iz zadane liste sve čvorove koji
sadrže studente koji su položili predmet prebaciti (bez
stvaranja novih čvorova) u novu jednostruko povezanu
listu. Funkcija treba vratiti pokazivač na glavu nove liste i
prosjek ocjena studenata koji su položili predmet.
Funkcija mora imati prototip:
atom *razdvojiStudente(atom **glava, float *prosjek);
13
Zadatak 3 nastavak
Napomena: U izvornoj listi na koju pokazuje glava ostaju
čvorovi koji sadrže studente čija ocjena nije dovoljna za
prolazak predmeta.
Primjer: Varijabla glava prije poziva funkcije pokazuje na listu
čvorova koji sadrže sljedeće ocjene:
5, 1, 4, 3, 4, 3, 2, 4, 5, 1.
Prosjek ocjena je 3,75 (vrijednost varijable prosjek) pa nakon
poziva funkcije razdvojiStudente ona vraća pokazivač na
novu listu koja sadrži čvorove sa sljedećim ocjenama:
5, 4, 3, 4, 3, 2, 4, 5.
Varijabla glava pokazuje na listu čvorova koji sadrže
preostale zapise.
14
Strategija rješavanja
• Slično kao i u prethodnom zadatku
• Radimo s novom listom: moramo čuvati adresu
prvog elementa (za povratnu vrijednost) i
zadnjeg elementa (za dodavanje u listu)
• Ništa ne free()-amo, samo prebacujemo zapise
(strukture) iz jedne liste u drugu – dakle samo
mijenjamo vrijednosti pokazivača u strukturama!
15
Zadatak 4 (ZI 2008)
a) Napišite funkciju čiji je prototip
int jeligomila(int stablo[], int n);
koja će vratiti 1 ako je potpuno binarno stablo s n elemenata
(implementirano poljem) gomila, a 0 inače.
b) Napišite funkciju čiji je prototip
int jeligomila(cvor *korijen);
koja će vratiti 1 ako je potpuno binarno stablo (čiji je korijen
zadan) gomila, a 0 ako nije.
16
Strategija riješavanja
• Moramo provjeriti da stablo ima svojstvo gomile,
znači:
1. Korijen je veći od lijevog i od desnog djeteta
2. Lijevo djete je veće od svog lijevog i od svog desnog
djeteta
3. Desno dijete je veće od svog lijevog i od svog
desnog djeteta
4. Lijevo djete lijevog djeteta je veće...
• Rekurzija? Dijelimo i vladamo 
17
Zadatak 5 (ZI 2012)
Za tip podatka Stog koji je realiziran jednostruko
povezanom listom definirane su funkcije za
inicijalizaciju stoga, dodavanje elementa na stog te
skidanje elementa sa stoga.
Zadana su dva stoga stog1 i stog2, a elementi
stogova su podaci tipa Osoba koji sadrže informaciju
o šifri osobe (cijeli broj) i visini (cijeli broj).
Stog stog1 sadrži podatke samo za muškarce, a
stog2 samo za žene i na oba stoga su podaci
sortirani po visini tako da je najviša osoba na vrhu
stoga.
18
Zadatak 5 nastavak
Prototipovi navedenih funkcija su:
void init_stog(Stog *stog);
int dodaj(Osoba element, Stog *stog);
int skini(Osoba *element, Stog *stog);
Funkcije dodaj i skini vraćaju 1 ako je operacija dodavanja ili
skidanja uspjela, a 0 inače.
a)(1 bod) Napišite definicije odgovarajućih struktura (tipovi
podataka Osoba, Stog i atom) za stog realiziran jednostruko
povezanom listom.
b)(7 bodova) Napišite rekurzivnu funkciju spoji koja će sa stoga
stog2 skinuti sve podatke i staviti ih na stog stog1, ali tako da
ostane očuvan poredak po visini. Poredak osoba s istom visinom
nije bitan.
19
Zadatak 5 nastavak
vrh->
345,
161,
654,
122,
234,
202
200
197
182
170
vrh->
348,
234,
111,
981,
203 vrh-> 348, 203
200
345, 202
189
234, 200
169
161, 200
654, 197
111, 189
122, 182
234, 170
981, 169
20
Strategija rješavanja
• Zamislimo da treba samo poskidati elemente sa
stoga i vratiti ih istim redosljedom
 Ako radim rekurzivno, mogu u prvom pozivu skinuti
prvi element, čuvati ga lokalno i rekurzivno riješiti
manji stog i nakon toga vratiti element na vrh
• U svakom koraku treba skinuti veći element sa
stoga
 Možemo skinuti oba, zatim usporediti i vratiti manji
nazad na stog s kojeg je skinut
 Samo moramo paziti da ne radimo s jednim ili oba
prazna stoga (kad su oba prazna je lako – to je kraj
rekurzije)
21