73
PROGRAMIRANJE 2 VEŽBE JEDNOSTRUKO I DVOSTRUKO POVEZANE LISTE. STEKOVI. Staša Vujičić Stanković

JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

  • Upload
    hanhu

  • View
    223

  • Download
    3

Embed Size (px)

Citation preview

Page 1: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

PROGRAMIRANJE 2

VEŽBE

JEDNOSTRUKO I DVOSTRUKO

POVEZANE LISTE. STEKOVI.

Staša Vujičić Stanković

Page 2: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

JEDNOSTRUKO POVEZANE LISTE. REKURZIVNO

#include <stdio.h>

#include <stdlib.h>

typedef struct cvor{

int vrednost;

struct cvor * sledeci;

} Cvor;

2

Page 3: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

void prikazi_elemente(Cvor *glava){

if(glava == NULL)

return;

printf(" %d",glava->vrednost);

prikazi_elemente(glava->sledeci);

}

void prikazi_listu(Cvor* glava){

putchar('[');

prikazi_elemente(glava);

printf("]\n");

} 3

Page 4: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* oslobodi_listu(Cvor* glava){

if(glava == NULL)

return NULL;

oslobodi_listu(glava->sledeci);

free(glava);

return NULL;

}

4

Page 5: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* napravi_cvor(int x){

Cvor* novi = (Cvor *)malloc(sizeof(Cvor));

if(novi == NULL)

return NULL;

novi->vrednost = x;

novi->sledeci = NULL;

return novi;

} 5

Page 6: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* dodaj_na_pocetak(Cvor* glava, int x){

Cvor *novi = napravi_cvor(x);

if(novi == NULL){

fprintf(stderr,"malloc() greska u funkciji

napravi_cvor()!\n");

glava = oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

/* uvezujemo ga na pocetak */

novi->sledeci = glava;

return novi;

}

6

Page 7: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* dodaj_na_kraj(Cvor* glava, int x){

if (glava == NULL){

Cvor* novi = napravi_cvor(x);

if(novi == NULL){

fprintf(stderr,"malloc() greska u funkciji

napravi_cvor()!\n");

glava = oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

return novi;

}

glava->sledeci = dodaj_na_kraj(glava->sledeci,x);

return glava;

}

7

Page 8: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* dodaj_sortirano(Cvor* glava, int x){

if(glava == NULL || glava->vrednost >= x )

return dodaj_na_pocetak(glava, x);

glava->sledeci = dodaj_sortirano(glava->sledeci, x);

return glava;

}

8

Page 9: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* pretrazi_listu(Cvor* glava, int x){

if(glava->vrednost == x)

return glava;

return pretrazi_listu(glava->sledeci, x);

}

9

Page 10: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Cvor* obrisi_element(Cvor* glava, int x){

if(glava == NULL)

return NULL;

glava->sledeci = obrisi_element(glava->sledeci,x);

if(glava->vrednost == x ){

Cvor* tekuci = glava->sledeci;

free(glava);

glava = tekuci;

}

return glava;

}… test program …

10

Page 11: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

JEDNOSTRUKO POVEZANE LISTE. ITERATIVNO

Prilikom promene liste (dodavanje novog elementa,

brisanje elementa, premeštanje elemenata, itd.)

postoji mogućnost da glava liste bude promenjena,

tj.

da to postane neki drugi čvor (sa drugom adresom).

U tom slučaju se pokazivač na glavu liste mora

ažurirati.

11

Page 12: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Kada promenu liste obavljamo u posebnoj funkciji

(kao što je bio slučaj u prethodnom primeru, gde

smo za dodavanje i brisanje imali posebne funkcije)

onda je potrebno da se

pozivajućoj funkciji vrati informacija o promeni

adrese glave,

kako bi pozivajuća funkcija mogla da ažurira svoju

pokazivačku promenljivu.

12

Page 13: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Ovo može da se uradi na dva načina:

1. Pozvana funkcija koja vrši promenu na listi

vraća kao povratnu vrednost adresu glave

nakon promene.

Ova adresa može biti ista kao i pre promene

(ako glava nije dirana) a može se i razlikovati.

U svakom slučaju, ta adresa treba da se dodeli

pokazivačkoj promenljivoj koja čuva adresu

glave u pozivajućoj funkciji.

Zbog toga se funkcija za promenu liste uvek

poziva na sledeći način:

pok = funkcija_za_promenu(pok, ...);

tj. promenljivoj čija se vrednost predaje kao

adresa glave u pozivu mora se dodeliti povratna

vrednost funkcije, za slučaj da je adresa glave

interno promenjena.

13

Page 14: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

2. Pozvana funkcija koja vrši promenu na listi prihvata

kao argument pokazivač na pokazivačku

promenljivu koja u pozivajućoj funkciji čuva adresu

glave i koju eventalno treba ažurirati.

Sada pozvana funkcija može interno da preko

dobijenog pokazivača promeni promenljivu

pozivajuće funkcije direktno. Npr:

funkcija_za_promenu(&pok, ...);

Funkcija koja se poziva je po pravilu void tipa.

Prednost drugog metoda je jednostavnije pozivanje,

dok je prednost prvog metoda jednostavnija sintaksa

unutar pozvane funkcije. 14

Page 15: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

JEDNOSTRUKO POVEZANE LISTE. ITERATIVNO

/* Struktura koja predstavlja cvor liste */

typedef struct cvor {

int vrednost; /* podatak koji cvor sadrzi */

struct cvor *sledeci; /* pokazivac na sledeci cvor */

} Cvor;

15

Page 16: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Pomocna funkcija koja kreira cvor.

Funkcija vrednost novog cvora inicijalizuje na broj,

dok pokazivac na sledeci cvor u novom cvoru

postavlja na NULL.

Funkcija ispisuje poruku o gresci i prekida program u

slucaju da malloc() funkcija ne uspe da alocira

prostor.

Funkcija vraca pokazivac na novokreirani cvor */

Cvor *napravi_cvor(int broj)

{

Cvor *novi = (Cvor *) malloc(sizeof(Cvor));

if(novi == NULL) return NULL;

novi->vrednost = broj;

novi->sledeci = NULL;

return novi;

}

16

Page 17: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija oslobadja dinamicku memoriju zauzetu

od strane liste. */

void oslobodi_listu(Cvor ** glava)

{

Cvor *pomocni;

while (*glava != NULL) {

/* moramo najpre zapamtiti adresu sledeceg

elementa, a tek onda osloboditi glavu */

pomocni = (*glava)->sledeci;

free(*glava);

*glava = pomocni;

}

} 17

Page 18: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija dodaje novi cvor na pocetak liste. Funkcija kreira

novi cvor koriscenjem funkcije napravi_cvor(). */

void dodaj_na_pocetak_liste(Cvor ** glava, int broj)

{

Cvor *novi = napravi_cvor(broj);

/* provera greske prilikom alokacije */

if(novi == NULL){

fprintf(stderr,"malloc() greska u funkciji napravi_cvor()!\n");

oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

/* uvezujemo novi cvor na pocetak */

novi->sledeci = *glava;

*glava = novi;

}

18

Page 19: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija dodaje novi cvor na kraj liste. Funkcija

kreira novi cvor koriscenjem funkcije napravi_cvor(). */

void dodaj_na_kraj_liste(Cvor ** glava, int broj)

{

Cvor *novi = napravi_cvor(broj);

Cvor *tekuci = *glava;

/* provera greske prilikom alokacije memorije */

if(novi == NULL){

fprintf(stderr,"malloc() greska u funkciji

napravi_cvor()!\n");

oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

19

Page 20: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* slucaj prazne liste. U tom slucaju je glava nove liste

upravo novi cvor. */

if (*glava == NULL) {

*glava = novi;

return;

}

/* Ako lista nije prazna, tada se krecemo duz liste sve

dok ne dodjemo do poslednjeg cvora (tj. do cvora ciji

pokazivac na sledeci pokazuje na NULL) */

while (tekuci->sledeci != NULL)

tekuci = tekuci->sledeci;

/* Dodajemo novi element na kraj preusmeravanjem

pokazivaca */

tekuci->sledeci = novi;

}

20

Page 21: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija dodaje novi element u sortiranu listu tako da i

nova lista ostane sortirana. Funkcija kreira novi cvor

koriscenjem funkcije napravi_cvor(). */

void dodaj_sortirano(Cvor ** glava, int broj)

{

Cvor *novi = napravi_cvor(broj);

Cvor *tekuci = *glava;

/* Proveravamo da li je doslo do greske prilikom alokacije

memorije */

if(novi == NULL){

fprintf(stderr,"malloc() greska u funkciji napravi_cvor()!\n");

oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

21

Page 22: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* u slucaju prazne liste glava nove liste je upravo

novi element */

if (*glava == NULL) {

*glava = novi;

return;

}

/* ako je novi element manji ili jednak od glave,

tada novi element mora da bude nova glava */

if ((*glava)->vrednost >= novi->vrednost) {

novi->sledeci = *glava;

*glava = novi;

return;

} 22

Page 23: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* u slucaju da je glava manja od novog elementa, tada

se krecemo kroz listu sve dok se ne dodje do elementa

ciji je sledeci element veci ili jednak od novog elementa,

ili dok se ne dodje do poslednjeg elementa. */

while (tekuci->sledeci != NULL

&& tekuci->sledeci->vrednost < novi->vrednost)

tekuci = tekuci->sledeci;

/* U svakom slucaju novi element dodajemo IZA tekuceg

elementa */

novi->sledeci = tekuci->sledeci;

tekuci->sledeci = novi;

} 23

Page 24: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija trazi u listi element cija je vrednost

jednaka datom broju.

Funkcija vraca pokazivac na cvor liste u kome je

sadrzan trazeni broj ili NULL u slucaju da takav

element ne postoji u listi */

Cvor *pretrazi_listu(Cvor * glava, int broj)

{

for (; glava != NULL; glava = glava->sledeci)

if (glava->vrednost == broj)

return glava;

return NULL;

} 24

Page 25: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija brise iz liste sve cvorove koji sadrze

dati broj.

Funkcija vraca pokazivac na glavu liste (koji moze

biti promenjen u slucaju da se obrise stara glava) */

void obrisi_element(Cvor ** glava, int broj)

{

Cvor *tekuci;

Cvor *pomocni;

25

Page 26: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Brisemo sa pocetka liste sve eventualne cvorove koji su

jednaki datom broju, i azuriramo pokazivac na glavu */

while (*glava != NULL && (*glava)->vrednost == broj) {

pomocni = (*glava)->sledeci;

free(*glava);

*glava = pomocni;

}

/* Ako je nakon toga lista ostala prazna prekidamo

funkciju */

if (*glava == NULL)

return;

26

Page 27: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Od ovog trenutka se u svakom koraku nalazimo na

tekucem cvoru koji je razlicit od trazenog broja (kao i svi

levo od njega).

Poredimo vrednost sledeceg cvora (ako postoji) sa

trazenim brojem i brisemo ga ako je jednak, a prelazimo

na sledeci cvor ako je razlicit.

Ovaj postupak ponavljamo dok ne dodjemo do poslednjeg

cvora. */

tekuci = *glava;

while (tekuci->sledeci != NULL)

if (tekuci->sledeci->vrednost == broj) {

pomocni = tekuci->sledeci;

tekuci->sledeci = tekuci->sledeci->sledeci;

free(pomocni);

} else

tekuci = tekuci->sledeci;

return;}

27

Page 28: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija prikazuje elemente liste pocev

od glave ka kraju liste */

void ispisi_listu(Cvor * glava)

{

putchar('[');

for (; glava != NULL; glava = glava->sledeci)

printf("%d ", glava->vrednost);

putchar(']');

putchar('\n');

} ...test program ...

28

Page 29: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

DVOSTRUKO POVEZANE LISTE.

#include <stdio.h>

#include <stdlib.h>

/* struktura kojom je predstavljen svaki element

liste */

typedef struct cvor{

int vrednost;

struct cvor *sledeci;

struct cvor *prethodni;

} Cvor; 29

Page 30: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija koja pravi nov cvor, inicijalizuje polje

vrednost u strukturi na broj i vraca pokazivac na

nov cvor */

Cvor* napravi_cvor(int broj)

{

Cvor* novi = (Cvor*)malloc(sizeof(Cvor));

if(novi == NULL)

return NULL;

/* inicijalizacija polja u novom cvoru */

novi->vrednost = broj;

novi->sledeci = NULL;

novi->prethodni = NULL;

return novi;

}

30

Page 31: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija oslobadja prostor koji smo alocirali za

elemente liste. */

Cvor* oslobodi_listu(Cvor* glava)

{

Cvor* pomocni;

while( glava != NULL )

{ pomocni = glava->sledeci;

free(glava);

glava = pomocni;

}

return NULL;

} 31

Page 32: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Fukcija kreira nov cvor sa poljem vrednost

postavljenim na broj i stavlja ga na pocetak liste. Nov

cvor je nova glava liste i vracamo pokazivac na nov

cvor. */

Cvor* dodaj_na_pocetak_liste(Cvor* glava, int

broj)

{

Cvor* novi = napravi_cvor(broj);

/* provera da li je doslo do greske prilikom alokacije */

if(novi == NULL)

{ fprintf(stderr, "malloc() greska u funkciji

napravi_cvor(%d)!\n",broj);

glava = oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

32

Page 33: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* sledeci od novog cvora je glava stare liste */

novi->sledeci = glava;

/* ako stara lista nije bila prazna, onda njena glava

nije NULL i moramo postaviti da prethodni od

glave bude nov cvor. */

if(glava != NULL)

glava->prethodni=novi;

return novi;

} 33

Page 34: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija nov cvor dodaje na kraj liste. */

Cvor* dodaj_na_kraj_liste( Cvor* glava, int broj)

{

Cvor* novi = napravi_cvor(broj);

Cvor* tekuci =glava;

/* provera da li je doslo do greske prilikom alokacije */

if(novi == NULL)

{ fprintf(stderr, "malloc() greska u funkciji

napravi_cvor(%d)!\n",broj);

glava = oslobodi_listu(glava);

exit(EXIT_FAILURE);

} 34

Page 35: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* ako je lista u koju dodajemo prazna. Nov cvor je

jedini cvor u novoj listi i time je i glava nove liste.

Pa vracamo novi. */

if(glava == NULL)

return novi;

/* tekuci pokazivac pomeramo da na sledeci

element liste dok ne dodjemo do poslednjeg

elementa u listi (tj. elementa koji ima NULL

pokazivac na polju sledeci). */

while( tekuci->sledeci != NULL)

tekuci = tekuci->sledeci;

35

Page 36: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* tada uvezujemo nov cvor na kraj, tako sto mu

azuriramo pokazivac na prethodni da pokazuje na

tekuci. A sledeci od tekuceg treba da bude nov cvor. */

tekuci->sledeci = novi;

novi->prethodni = tekuci;

return glava;

}

36

Page 37: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Fukcija dodaje u listu nov cvor na odgovarajuce

mesto. Tj. Funkcija pronalazi odgovarajuci cvor u listi

iza kod treba uvezati nov cvor. */

Cvor* dodaj_sortirano(Cvor* glava, int broj)

{

Cvor* novi = napravi_cvor(broj);

Cvor* tekuci = glava;

/* provera da li je doslo do greske prilikom alokacije */

if(novi == NULL)

{ fprintf(stderr, "malloc() greska u funkciji

napravi_cvor(%d)!\n",broj);

glava = oslobodi_listu(glava);

exit(EXIT_FAILURE);

}

37

Page 38: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* ako je lista u koju ubacujemo nov cvor prazna,

nov cvor upravo i jedini cvor u novoj listi,

pa je i glava nove liste.*/

if( glava == NULL)

return novi;

/* Lista nije prazna*/

/* Ukoliko je vrednost glave liste veca od nove

vrednosti onda nov cvor treba da uvezati pre glave,

tj. staviti na pocetak liste. */

if( glava->vrednost >= broj)

{

novi->sledeci = glava;

glava->prethodni = novi;

return novi;

}

38

Page 39: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Pomeramo pokazivac tekuci da pokazuje na svoj

sledeci sve dok su vrednosti njegovog sledeceg manji od

nove vrednosti ili dok ne dodjemo do poslednjeg

elementa u listi.*/

while(tekuci->sledeci != NULL && tekuci->sledeci-

>vrednost < novi->vrednost)

tekuci = tekuci->sledeci;

novi->sledeci = tekuci->sledeci;

novi->prethodni = tekuci;

39

Page 40: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* ako smo iz prethodne petlje izasli zato sto je

tekuci pokazivac na poslednji element u listi */

if( tekuci->sledeci != NULL )

tekuci->sledeci->prethodni = novi;

tekuci->sledeci = novi;

/* vracamo pokazivac na glavu cele liste*/

return glava;

}

40

Page 41: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Fukcija prolazi kroz listu od glave do kraja liste

u potrazi za cvorom koji na polju vrednost ima

trazenu vrednost broj. */

Cvor* pretrazi_listu(Cvor* glava, int broj)

{

for( ; glava!=NULL; glava = glava->sledeci)

if( glava->vrednost == broj)

/* nasli smo cvor sa trazenom vrednoscu i vracamo

pokazivac na njega. */

return glava;

/* dosli smo do kraja liste i nismo nasli trazeni

element. pa vracamo NULL. */

return NULL;

}

41

Page 42: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funckija brise u listi na koju pokazuje pokazivac

glava bas onaj cvor na koji pokazuje pokazivac

tekuci. Obratiti paznju da je kod dvostruke liste

ovo mnogo lakse uraditi jer cvor tekuci sadrzi

pokazivace na svog sledbenika i prethodnika u listi.

Pre nego sto fizicki obrisemo tekuci obavezno

moramo azurirati sve pokazivace sledbenika i

prethodnika. */

Cvor* obrisi_tekuci(Cvor* glava, Cvor*

tekuci)

{

/* ako je tekuci NULL pokazivac nema sta da se

brise. */

if(tekuci == NULL)

return glava; 42

Page 43: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Ako postoji prethodnik od tekuceg onda se

postavlja da njegov sledeci bude sledeci od tekuceg */

if( tekuci->prethodni != NULL)

tekuci->prethodni->sledeci = tekuci->sledeci;

/* Ako postoji sledbenik tekuceg (cvora koji bismo

obrisali) onda njegov prethodnik treba da bude

prethodnik od tekuceg */

if(tekuci->sledeci != NULL)

tekuci->sledeci->prethodni =

tekuci->prethodni;

43

Page 44: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* ako je glava element koji se brise. Glava nove

liste postaje sledbenik od glave. */

if( tekuci == glava)

glava = tekuci->sledeci;

/* oslobadjamo dinamicki alociran prostor za cvor

tekuci*/

free(tekuci);

return glava;

} 44

Page 45: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Brisemo element u listi cije polje vrednost je

trazeni broj */

Cvor* obrisi_element(Cvor* glava, int broj)

{

Cvor* tekuci = glava;

Cvor* pomocni;

while((tekuci = pretrazi_listu(glava,broj)) != NULL)

{ pomocni = tekuci->sledeci;

glava = obrisi_tekuci(glava, tekuci);

tekuci = pomocni;

}

return glava;

} 45

Page 46: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija ispisuje vrednosti iz liste. */

void ispisi_listu(Cvor* glava)

{

putchar('[');

for( ;glava != NULL; glava = glava->sledeci)

printf("%d ",glava->vrednost);

putchar(']');

putchar('\n');

}

46

Page 47: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija prikazuje elemente liste pocev od kraja

ka glavi liste. Kod dvostruko povezane to je jako

jednostavno jer svaki cvor ima pokazivac na

prethodni element u listi. */

void ispisi_listu_u_nazad(Cvor* glava)

{

putchar('[');

if(glava == NULL )

{ printf("]\n");

return;

}

47

Page 48: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* pomeramo pokazivac glava sve dok ne pokazuje

na poslednji element u listi*/

while(glava->sledeci != NULL)

glava = glava->sledeci;

/* ispisujemo element po element liste unazad.

Pristupamo elementu liste i nakon ispisa

pomeramo pokazivac glava da pokazuje na

prethodnika */

for( ;glava != NULL; glava = glava->prethodni)

printf("%d ", glava->vrednost);

printf("]\n");

} ... test program ... 48

Page 49: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

STEKOVI

Stek (eng. stack) je struktura podataka nad

kojom su definisane sledeće operacije:

1. Dodavanje elementa –

kažemo da je element potisnut na vrh steka

(eng. push() operacija)

2. Uklanjanje elementa koji je poslednji dodat –

kažemo da je element skinut sa vrha steka

(eng. pop() operacija)

3. Očitavanje vrednosti elementa koji je poslednji

dodat

(eng. top() operacija) 49

Page 50: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

Stek spada u LIFO strukture

(eng. Last In First Out).

Može se implementirati na više načina.

Najjednostavniji način je da se definiše kao niz.

Međutim, tada je ograničen maksimalan broj elemenata

na steku dimenzijom niza.

Zbog toga se obično koriste liste za implementaciju steka,

gde se push() operacija svodi na dodavanje na početak, a

pop() operacija se svodi na uklanjanje glave liste.

Obe operacije se izvode u konstantnom vremenu.

50

Page 51: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Program proverava da li su etikete u datom

HTML fajlu dobro uparene */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#define MAX 100

#define OTVORENA 1

#define ZATVORENA 2

#define VAN_ETIKETE 0

#define PROCITANO_MANJE 1

#define U_ETIKETI 2 51

Page 52: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Struktura koja predstavlja cvor liste */

typedef struct cvor {

char etiketa[MAX]; /* Sadrzi ime etikete */

struct cvor *sledeci; /* pokazivac na sledeci cvor */

} Cvor;

52

Page 53: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija kreira novi cvor, upisuje u njega etiketu

i vraca njegovu adresu */

Cvor *napravi_cvor(char *etiketa)

{

Cvor *novi = NULL;

if ((novi = (Cvor *) malloc(sizeof(Cvor))) == NULL) {

fprintf(stderr, "malloc() greska!\n");

exit(1);

}

53

Page 54: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

if (strlen(etiketa)>=MAX) {

fprintf(stderr, "Etiketa koju pokusavamo staviti na

stek preduga.\n");

exit(1);

}

strcpy(novi->etiketa, etiketa);

novi->sledeci = NULL;

return novi;

} 54

Page 55: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija postavlja na vrh steka novu etiketu */

void potisni_na_stek(Cvor ** vrh, char *etiketa)

{

Cvor *novi = napravi_cvor(etiketa);

novi->sledeci = *vrh;

*vrh = novi;

}

55

Page 56: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija skida sa vrha steka etiketu. Ako je

drugi argument pokazivac razlicit od NULL,

tada u niz karaktera na koji on pokazuje upisuje

ime etikete koja je upravo skinuta sa steka dok u

suprotnom ne radi nista.

Funkcija vraca 0 ako je stek prazan (pa samim tim

nije bilo moguce skinuti vrednost sa steka)

ili 1 u suprotnom. */

int skini_sa_steka(Cvor ** vrh, char *etiketa)

{

Cvor *pomocni;

56

Page 57: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* pokusavamo da skinemo vrednost sa vrha

praznog steka i imamo gresku. */

if (*vrh == NULL)

return 0;

/* Ako adresa na koju zelimo da smestamo etiketu

nije NULL kopiramo tamo etiketu sa vrha steka. */

if (etiketa != NULL)

strcpy(etiketa, (*vrh)->etiketa);

/* oslobadjamo element sa vrha steka */

pomocni = *vrh;

*vrh = (*vrh)->sledeci;

free(pomocni);

return 1;

}

57

Page 58: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija vraca pokazivac na string koji sadrzi

etiketu na vrhu steka. Ukoliko je stek prazan,

vraca NULL */

char *vrh_steka(Cvor * vrh)

{

if (vrh == NULL)

return NULL;

return vrh->etiketa;

}

58

Page 59: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija prikazuje stek pocev od vrha prema dnu */

void prikazi_stek(Cvor * vrh)

{

for ( ; vrh != NULL; vrh = vrh->sledeci)

printf("<%s>\n", vrh->etiketa);

}

59

Page 60: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija prazni stek */

void oslobodi_stek(Cvor ** vrh)

{

Cvor *pomocni;

while (*vrh != NULL) {

pomocni = *vrh;

*vrh = (*vrh)->sledeci;

free(pomocni);

}

} 60

Page 61: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Funkcija iz fajla na koji pokazuje f cita sledecu

etiketu, i njeno ime upisuje u niz na koji pokazuje

pokazivac etiketa.

Funkcija vraca EOF u slucaju da se dodje do kraja fajla

pre nego sto se procita etiketa,

vraca OTVORENA ako je procitana otvorena etiketa,

odnosno ZATVORENA ako je procitana zatvorena etiketa.

*/

int uzmi_etiketu(FILE * f, char *etiketa)

{

61

Page 62: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

int c; /* prihvata karakter iz datoteke*/

int stanje = VAN_ETIKETE; /* stanje nam cuva

informaciju dokle smo citali sa citanjem etikete

inicijalno smo ga postavili na vrednost

VAN_ETIKETE jer jos uvek nismo poceli da

citamo.*/

int i = 0;

int tip;

/* cuva informaciju o tipu etikete uzima vrednosti

OTVORENA, ZATVORENA */

62

Page 63: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

while ((c = fgetc(f)) != EOF) {

switch (stanje) {

case VAN_ETIKETE:

if (c == '<')

stanje = PROCITANO_MANJE;

break;

63

Page 64: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

case PROCITANO_MANJE:

if (c == '/')

/* citamo zatvarac */

tip = ZATVORENA;

else if (isalpha(c)) {

/* citamo otvarac */

tip = OTVORENA;

etiketa[i++] = tolower(c);

/* HTML je CaseInsensitive. U HTML-u etikete BODY i

body imaju isto znacenje, dok to u C-u nece vaziti.*/

}

stanje = U_ETIKETI;

/* poceli smo sa citanjem etikete, pa menjamo i stanje */

break; 64

Page 65: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

case U_ETIKETI:

/* citamo etiketu */

if (isalpha(c) && i < MAX - 1)

/* ako je procitani karakter slovo i nismo premasili maksimalnu

dozvoljenu duzinu za etiketu*/

etiketa[i++] = tolower(c);

/* smestamo procitani karakter u etiketu*/

else {

stanje = VAN_ETIKETE;

/* u suprotnom, prestajemo sa citanjem etikete i menjamo stanje. */

etiketa[i] = '\0';

return tip;

/* zavrsili smo sa citanjem etikete i vracamo tip etikete koju smo

procitali, a ona nam je sacuvana nisci etiketa*/

}

break;}

65

Page 66: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

}

/* dosli smo do kraja datoteke pre nego sto smo

zavrsili sa citanjem etikete , stoga imamo gresku i

vracamo EOF*/

return EOF;

}

66

Page 67: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Test program */

int main(int argc, char **argv)

{

Cvor *vrh = NULL;

char etiketa[MAX];

int tip;

int uparene = 1; /* na pocetku su nam etikete

upare, jer nismo nijednu jos uvek procitali. */

FILE *f; 67

Page 68: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Ime datoteke zadajemo na komandnoj liniji */

if (argc < 2) {

fprintf(stderr, "Koriscenje: %s ime_html_datoteke\n",

argv[0]);

exit(0);

}

/* Otvaramo datoteku */

if ((f = fopen(argv[1], "r")) == NULL) {

fprintf(stderr, "fopen() greska!\n");

exit(1);

} 68

Page 69: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Dokle god ima etiketa, uzimamo ih jednu po jednu

sa ulaza */

while ((tip = uzmi_etiketu(f, etiketa)) != EOF) {

/* Ako je otvorena etiketa, dodajemo je na stek.

Izuzetak su etikete <br>, <hr> i <meta> koje nemaju

sadrzaj, tako da ih nije potrebno zatvoriti.

NAPOMENA: U html-u postoje jos neke etikete koje

koje nemaju sadzaj (npr link). Pretpostavimo da njih

nema u dokumentu, zbog jednostavnosti */

if (tip == OTVORENA) {

if (strcmp(etiketa, "br") != 0 &&

strcmp(etiketa, "hr") != 0 &&

strcmp(etiketa, "meta") != 0)

potisni_na_stek(&vrh, etiketa);

} 69

Page 70: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Ako je zatvorena etiketa, tada je uslov dobre

uparenosti da je u pitanju zatvaranje etikete koja

je poslednja otvorena, a jos uvek nije zatvorena.

Ova etiketa se mora nalaziti na vrhu steka.

Ako je taj uslov ispunjen, tada je skidamo sa steka,

jer je zatvorena.

U suprotnom, obavestavamo korisnika da etikete

nisu pravilno uparene. */

70

Page 71: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

else if (tip == ZATVORENA) {

if (vrh_steka(vrh) != NULL &&

strcmp(vrh_steka(vrh), etiketa) == 0)

skini_sa_steka(&vrh, NULL);

else {

printf(vrh_steka(vrh) != NULL ?

"Etikete nisu pravilno uparene\n(nadjena etiketa </%s> a

poslednja otvorena etiketa je <%s>)\n"

:

"Etikete nisu pravilno uparene\n(nadjena etiketa </%s>

koja nije otvorena)\n", etiketa, vrh_steka(vrh));

uparene = 0;

break; }

}

}

71

Page 72: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

/* Zatvaramo fajl */

fclose(f);

/* Ako nismo pronasli pogresno uparivanje... */

if (uparene) {

/* Nakon zavrsetka citanja etiketa uslov je da stek

mora biti prazan. Ako nije, tada znaci da postoje jos

neke etikete koje su otvorene ali nisu zatvorene. */

72

Page 73: JEDNOSTRUKO I DVOSTRUKO LISTE TEKOVIstasa/P2/Cas 11.pdf · /* Pomocna funkcija koja kreira cvor. Funkcija vrednost novog cvora inicijalizuje na broj, dok pokazivac na sledeci cvor

if (vrh_steka(vrh) == NULL)

printf("Etikete su pravilno uparene!\n");

else

printf("Etikete nisu pravilno

uparene\n(etiketa <%s> nije zatvorena)\n",

vrh_steka(vrh));

}

/* Oslobadjamo stek */

oslobodi_stek(&vrh);

return 0;

} 73