Professional Documents
Culture Documents
Algoritmi I Strukture Podaraka Kruzne Liste
Algoritmi I Strukture Podaraka Kruzne Liste
1
Kružna jednostruko povezana lista
10 30 50 55 80
zadnji
2
Motivacija
3
Definicija kružne jednostruko
povezane liste
struct Cvor{
int podatak;
Cvor* slijedeci;
};
Cvor *zadnji=0;
4
Operacije na kružnoj jednostruko
povezanoj listi
ispis(Cvor * zadnji)
//ispisuje elemente kružne povezane liste
5
Obilazak liste
void ispis(Cvor * zadnji){
Cvor * tekuci;
if(zadnji != 0){ // za nepraznu listu
tekuci = zadnji->slijedeci; // počinjemo sa 1. elementom
do{
cout << tekuci->podatak << " ";
tekuci = tekuci->slijedeci;
}while(tekuci != zadnji->slijedeci);
cout << endl;
}
10 30 35 55 60
6
zadnji
Umetanje čvora
Umetanje u praznu listu
20
zadnji = novi;
zadnji->slijedeci = zadnji; // to je i prvi čvor
7
Umetanje prvog čvora (glave) u kružnu
povezanu listu (između preth i tekuci)
Cvor * novi = new Cvor;
novi->podatak = 20;
novi->slijedeci = tekuci;
// isto kao: novi->slijedeci = zadnji->slijedeci;
preth->slijedeci = novi; // isto kao: zadnji->slijedeci = novi;
20 35 40 65 70
5 30 55 70
40
preth tekuci zadnji
novi
9
Umetanje na kraj kružne povezane liste
novi->slijedeci = tekuci;
// isto kao: novi->slijedeci = zadnji->slijedeci;
preth->slijedeci = novi;
// isto kao: zadnji->slijedeci = novi;
zadnji = novi; // novi čvor postaje zadnji u listi
10 30 40 55 70
5 30 55 70
40
preth tekuci zadnji
novi
12
Brisanje čvora
Brisanje čvora u jednočlanoj kružnoj
povezanoj listi
zadnji = NULL;
40
delete tekuci;
13
Brisanje čvora na mjestu glave liste u
kružnoj povezanoj listi
preth->slijedeci = tekuci->slijedeci;
// isto kao: zadnji->slijedeci = tekuci->slijedeci
delete tekuci;
5 30 50 55 90
zadnji preth
tekuci
14
Brisanje čvora tekuci u sredini kružne
povezane liste
preth->slijedeci = tekuci->slijedeci;
delete tekuci;
5 10 20 75 90
15
Brisanje zadnjeg čvora u kružnoj povezanoj
listi
preth->slijedeci = tekuci->slijedeci;
// isto kao: zadnji->slijedeci;
delete tekuci;
zadnji = preth;
5 10 15 25 30
preth tekuci
zadnji 16
void brisiCvor(Cvor *& zadnji, int broj){
Cvor *tekuci, *preth;
if(zadnji == NULL){
cout << "Lista je prazna!" << endl;
return;
}
preth = zadnji;
tekuci = zadnji->slijedeci;
do{ // nađi preth i tekuci
if(broj <= tekuci->podatak) break; // uređena lista
preth = tekuci;
tekuci = tekuci->slijedeci;
}while(tekuci != zadnji->slijedeci);
17
if(tekuci->podatak != broj){ //podatak nije u listi
cout << "Podatak nije nadjen!" << endl;
return;
}
if(tekuci == preth){ // briši jedini čvor liste
zadnji = NULL;
delete tekuci;
return;
}
if(tekuci == zadnji) // usmjeri pokazivač zadnji
zadnji = preth; // ako se briše kraj liste
preth->slijedeci = tekuci->slijedeci; // preusmjeri
delete tekuci; // pokazivače
}
18
void main(){
Cvor *zadnji = NULL;
Izvorni kod: kpl1.cpp
umetniCvor(zadnji, 2);
umetniCvor(zadnji, 3);
umetniCvor(zadnji, 6);
umetniCvor(zadnji, 4);
umetniCvor(zadnji, 9);
ispis(zadnji);
brisiCvor (zadnji, 2);
brisiCvor(zadnji, 9);
brisiCvor(zadnji, 3); Ispis:
ispis(zadnji); 23469
umetniCvor(zadnji, 7); 46
umetniCvor(zadnji, 9); 4679
ispis(zadnji);
}
19
Dvostruko povezana lista
U dvostruko povezanoj listi svaki čvor je
povezan i sa prethodnim i sa slijedećim
čvorom.
preth pokazuje na prethodnika
slijedeci pokazuje na sljedbenika
10 30 50 55 70
glava
tekuci->preth tekuci tekuci->slijedeci
20
Motivacija
Dvostruko povezana lista je korisna za
prikaz video i zvučnih zapisa (u
datotekama), uz premotavanje (rewind) i
ponovni prikaz (instant replay).
Korisne su i za druge povezane podatke
koji zahtijevaju "premotavanje unatrag" i
"brzi prijelaz podataka" (fast forward).
Prikaz snopa karata u igri, “undo” u
Wordu, cache memorija pretraživača,
binarno stablo
21
Definicija dvostruko povezane liste
struct Cvor{
int podatak;
Cvor* slijedeci;
Cvor* preth;
};
Cvor *glava;
22
Operacije na dvostruko povezanoj
listi
umetniCvor(Cvor *&glava, int podatak)
dodaje novi čvor u uređenu dvostruko povezanu listu
ispis(Cvor *glava)
23
ispisuje elemente liste
Brisanje čvora
Brisanje čvora tekuci (nije prvi ni zadnji)
(tekuci->preth)->slijedeci = tekuci->slijedeci;
(tekuci->slijedeci)->preth = tekuci->preth;
delete tekuci;
10 30 40 65 80
glava
tekuci
24
Umetanje čvora
Umetanje čvora novi prije čvora tekuci
(nije prvi ni zadnji)
novi->slijedeci = tekuci;
novi->preth = tekuci->preth;
tekuci->preth = novi;
(novi->preth)->slijedeci = novi;
10 30 65 80
glava 40
tekuci
novi 25
Dvostruko povezane liste sa lažnim
prvim čvorom
Da bi pojednostavili umetanje i brisanje
i izbjegli slučajeve brisanja i umetanja
na mjestu prvog i zadnjeg elementa, na
početak liste dodajemo lažni čvor.
Zadnji čvor pokazuje na lažni prvi čvor
kao svog sljedbenika.
26
Dvostruko povezane liste sa lažnim prvim
čvorom
Neprazna lista
Lažni čvor
10 30 40 55 80
glava
glava
27
void kreirajGlavu(Cvor*& glava){
glava = new Cvor;
glava->slijedeci = glava;
glava->preth = glava;
}
28
Brisanje čvora
Brisanje čvora tekuci na početku
(tekuci->preth)->slijedeci = tekuci->slijedeci;
(tekuci->slijedeci)->preth = tekuci->preth;
delete tekuci;
Lažni čvor
10 30 40 65 80
glava tekuci
29
Brisanje čvora tekuci u sredini
(tekuci->preth)->slijedeci = tekuci->slijedeci;
(tekuci->slijedeci)->preth = tekuci->preth;
delete tekuci; // isto kao brisanje prvoga!
Lažni čvor
10 30 40 65 70
tekuci
glava
30
Brisanje čvora tekuci kao zadnjeg
čvora liste
(tekuci->preth)->slijedeci = tekuci->slijedeci;
(tekuci->slijedeci)->preth = tekuci->preth;
delete tekuci; // isto kao brisanje prvog i srednjeg
čvora!
Lažni čvor
10 30 40 65 70
glava tekuci
31
void brisicvor(Cvor * glava, int broj){
Cvor * tekuci;
tekuci = traziCvor(glava, broj);
if(tekuci != NULL){
tekuci->preth->slijedeci = tekuci->slijedeci;
tekuci->slijedeci->preth = tekuci->preth;
delete tekuci;
}
}
32
Umetanje čvora
Umetanje čvora novi nakon lažnog
čvora a prije čvora tekuci
novi->slijedeci = tekuci;
novi->preth = tekuci->preth;
tekuci->preth = novi;
(novi->preth)->slijedeci = novi;
Lažni čvor
30
10
glava novi tekuci
33
Umetanje čvora novi u sredinu prije čvora
tekuci
novi->slijedeci = tekuci;
novi->preth = tekuci->preth;
tekuci->preth = novi;
(novi->preth)->slijedeci = novi; // isto kao umetanje na
// početak!
Lažni čvor
10 30 65
40
novi tekuci
glava
34
Umetanje čvora novi na poziciju zadnji
(tekuci pokazuje na lažan čvor)
novi->slijedeci = tekuci;
novi->preth = tekuci->preth;
tekuci->preth = novi;
(novi->preth)->slijedeci = novi; // isto kao umetanje na
// početak!
Lažni čvor
10 30 40 65 70
35
Umetanje čvora novi u praznu listu
(tekuci pokazuje na lažan čvor)
novi->slijedeci = tekuci;
novi->preth = tekuci->preth;
tekuci->preth = novi;
(novi->preth)->slijedeci = novi;
Lažni čvor
30
36
void umetniCvor(Cvor *glava, int broj){
Cvor *novi, *tekuci;
novi = new Cvor;
novi->podatak = broj;
38
Traženje čvora:
Cvor * traziCvor(Cvor *glava, int broj){
Cvor * tekuci = glava->slijedeci;
while(tekuci != glava){
if(tekuci->podatak == broj)
return tekuci;
if(tekuci->podatak < broj)
tekuci = tekuci->slijedeci;
else
break;
}
return NULL;
} 39
Ispis liste:
40
void main(){
Cvor *glava, *temp;
kreirajGlavu(glava);
Izvorni kod: kdpl1.cpp
ispis(glava);
umetniCvor(glava, 2);
ispis(glava);
umetniCvor(glava, 6);
ispis(glava);
umetniCvor(glava, 7);
ispis(glava); Ispis:
umetniCvor(glava, 4);
umetniCvor(glava, 3); 2
umetniCvor(glava, 9); 26
ispis(glava); 267
brisiCvor(glava, 5); 234679
brisiCvor(glava, 6); 23479
ispis(glava); Podatak se nalazi u listi.
temp = traziCvor(glava, 7);
if(temp != NULL)
cout << "Podatak se nalazi u listi." << endl;
else
cout << "Podatak se ne nalazi u listi." << endl;
41
}
Višestruko povezane liste
43
Primjeri sa kviza
1. Slijedeća funkcija treba vratiti duljinu povezane liste. Što
nije u redu?
int duljina(Cvor *glava) {
int velicina = 0;
Cvor * tekuci;
while(tekuci != NULL){
velicina++;
tekuci = tekuci->slijedeci;
}
}
44
2. Slijedeća funkcija treba ispisati kružnu jednostruko
povezanu listu. Što nije u redu?
45
3. Slijedeća funkcija treba kreirati lažan prvi čvor dvostruko
povezane liste. Što nije u redu?
void kreirajGlavu(Cvor * glava){
glava = new Cvor;
glava->slijedeci = NULL;
glava->preth = NULL;
}
46