Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
PROGRAMIRANJE 2
VEŽBE
REDOVI. BINARNA STABLA.
Staša Vujičić Stanković
REDOVI
Red (eng. queue) je struktura podataka nad kojom su
definisane sledeće operacije:
1. Dodavanje elementa –
kažemo da je element dodat na kraj reda
(eng. enqueue() operacija)
2. Uklanjanje elementa koji je prvi dodat –
kažemo da je element skinut sa početka reda
(eng. dequeue() operacija)
3. Očitavanje vrednosti elementa koji je na početku reda
(eng. front() operacija)
2
3
Red spada u FIFO strukture
(eng. First In First Out).
Može da se implementira na više načina.
Najjednostavniji način je da se definiše kao niz.
Međutim, tada je dimenzijom niza ograničen
maksimalan broj elemenata u redu.
Zbog toga se obično pribegava korišćenju lista
za implementaciju reda, gde se:
enqueue() operacija svodi na dodavanje na kraj liste,
dequeue() operacija se svodi na uklanjanje glave liste.
Obe operacije se izvode u konstantnom vremenu,
pod uslovom da se osim pokazivača na glavu liste
čuva i pokazivač na poslednji element u listi.
4
ZADATAK
Skupovi brojeva su predstavljeni tekstualnim
fajlovima koji sadrže brojeve i imena drugih fajlova.
Na primer:
Fajl S1: 1 2 3 4 s2 5 6 s3 7 8 9 s4 1
Fajl S2: 12 14 16 s5 17
Fajl S3: 21 23 25 27 29
Fajl S4: 32 37 31 36
Fajl S5: 56 62 68 69 70
5
Ako se broj x nalazi u fajlu S1,
tada broj x pripada skupu S1.
Ako se ime fajla S1 nalazi u fajlu S2,
tada je skup S1 podskup skupa S2.
Program za dati skup S i dati broj x proverava
da li x pripada S.
6
KOMENTAR
U ovom zadatku će red biti korišćen na sledeći način:
Inicijalno se u red stavlja ime fajla koji predstavlja
dati skup S.
Prilikom čitanja fajla, svaki put kada se naiđe na
ime drugog fajla, to ime se dodaje u red.
Kada se završi sa čitanjem tekućeg fajla,
isti se zatvara, skida se sa reda sledeći fajl i
čitanje se nastavlja u njemu.
Ovaj proces se ponavlja dok se ne naiđe na traženi
broj, ili dok se ne isprazni red. 7
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
/* Struktura koja predstavlja cvor liste */
typedef struct cvor {
char ime_fajla[MAX]; /* Sadrzi ime fajla */
struct cvor *sledeci; /* pokazivac na sledeci cvor */
} Cvor;
8
/* Funkcija kreira novi cvor, upisuje u njega ime fajla i
vraca adresu novog cvora ili NULL ako je doslo do greske
pri alokaciji.
Ako je doslo do greske, trebalo bi osloboditi ceo red.
Ostavljamo da to uradi funkcija koja je pozvala funkciju
napravi_cvor, a gresku joj signaliziramo saljuci joj NULL.*/
Cvor *napravi_cvor(char *ime_fajla)
{
Cvor *novi = NULL;
if ((novi = (Cvor *) malloc(sizeof(Cvor))) == NULL)
return NULL;
strcpy(novi->ime_fajla, ime_fajla);
novi->sledeci = NULL;
return novi;
} 9
/* Funkcija prazni red */
void oslobodi_red(Cvor ** pocetak, Cvor ** kraj)
{
Cvor *pomocni;
while (*pocetak != NULL) {
pomocni = *pocetak;
*pocetak = (*pocetak)->sledeci;
free(pomocni);
}
*kraj = NULL;
}
10
/* Funkcija dodaje na kraj reda novi fajl */
void dodaj_u_red(Cvor ** pocetak, Cvor ** kraj,
char *ime_fajla)
{
Cvor *novi = napravi_cvor(ime_fajla);
/* Ako funkcija napravi_cvor nije alocirala novi cvor,
praznimo red, prijavljujemo gresku i prekidamo
program. */
if(novi == NULL){
fprintf(stderr,"GRESKA:
malloc() u funkciji napravi_cvor()\n");
oslobodi_red(pocetak, kraj);
exit(EXIT_FAILURE);
}
if (*kraj != NULL) {
(*kraj)->sledeci = novi;
*kraj = novi;
} else {
/* ako je red prazan */
*pocetak = novi;
*kraj = novi;
}
}
12
/* Funkcija skida sa pocetka reda ime fajla.
Ako je poslednji argument pokazivac razlicit od
NULL, tada u niz karaktera na koji on pokazuje
upisuje ime fajla koji je upravo skinut sa reda
dok se u suprotnom ne radi nista.
Funkcija vraca 0 ako je red prazan
(pa samim tim nije bilo moguce skinuti vrednost sa
reda) ili 1 u suprotnom. */
int skini_sa_reda(Cvor ** pocetak, Cvor ** kraj,
char *ime_fajla)
{
Cvor *pomocni;
if (*pocetak == NULL)
return 0;
13
if (ime_fajla != NULL)
strcpy(ime_fajla, (*pocetak)->ime_fajla);
pomocni = *pocetak;
*pocetak = (*pocetak)->sledeci;
free(pomocni);
if (*pocetak == NULL)
*kraj = NULL;
return 1;
}
14
/* Funkcija prikazuje red */
void prikazi_red(Cvor * pocetak)
{
for (; pocetak != NULL; pocetak = pocetak->sledeci)
printf("%s, ", pocetak->ime_fajla);
printf("\n");
}
15
/* Glavni program */
int main(int argc, char **argv)
{
Cvor *pocetak = NULL, *kraj = NULL;
FILE *in = NULL;
char file[MAX];
int broj, x;
int pronadjen = 0;
16
/* NAPOMENA: Pretpostavlja se da nema cirkularnih
zavisnosti, tj. da ne moze da se desi slucaj:
S2 podskup od S1, S3 podskup S2,...,S1 podskup od Sn,
u kom slucaju bismo imali beskonacnu petlju. */
/* Ime fajla i broj se zadaju sa komandne linije */
if (argc < 3) {
fprintf(stderr, "GRESKA! Program se poziva sa %s
ime_fajla broj\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Dodajemo skup S u red */
dodaj_u_red(&pocetak, &kraj, argv[1]);
/* Trazeni broj x */
broj = atoi(argv[2]); 17
/* Dokle god broj nije pronadjen, a ima jos fajlova u redu */
while (!pronadjen && skini_sa_reda(&pocetak, &kraj, file))
{
/* Otvaramo sledeci fajl sa reda */
if ((in = fopen(file, "r")) == NULL) {
fprintf(stderr, "Greska prilikom otvaranja fajla:
%s\n", file);
oslobodi_red(&pocetak, &kraj);
exit(EXIT_FAILURE);
}
18
/* Dokle god nismo stigli do kraja fajla i nismo pronasli broj */
while (!feof(in) && !pronadjen) {
/* Ako je broj sledeci podatak u fajlu */
if (fscanf(in, "%d", &x) == 1) {
/* Ako je nadjen trazeni broj */
if (broj == x) {
printf("Broj x=%d pripada skupu!\n", x);
pronadjen = 1;
}
}
/* Ako je ime fajla sledeci podatak u fajlu */
else if (fscanf(in, "%s", file) == 1) {
/* Dodajemo ga u red */
dodaj_u_red(&pocetak, &kraj, file);
} }
19
/* Zatvaramo fajl */
fclose(in);
}
/* Ako do kraja nije pronadjen */
if (!pronadjen)
printf("Broj x=%d ne pripada skupu!\n", broj);
/* Oslobadjamo red */
oslobodi_red(&pocetak, &kraj);
return 0;
}
20
BINARNA UREĐENA STABLA
Uređeno stablo je stablo u kome su deca svakog
čvora uređena u nekom poretku.
Binarno uređeno stablo je uređeno stablo u kome
svi unutrašnji čvorovi imaju stepen 2.
21
ZADATAK
/* NAPOMENA: Ova verzija programa ne oslobadja
stablo ukoliko se dogodi greska pri alociranju
prostora za nov cvor sa funkcijom malloc().
Samo se prijavljuje greska i prekida program. */
#include <stdio.h>
#include <stdlib.h>
/* struktura kojom se predstavlja cvor drveta */
typedef struct dcvor{
int broj;
struct dcvor* levo, *desno;
} Cvor;
22
/* Funkcija alocira prostor za novi cvor drveta,
inicijalizuje polja strukture i vraca pokazivac na nov cvor
*/
Cvor* napravi_cvor(int b )
{ Cvor* novi = (Cvor*) malloc(sizeof(Cvor));
if( novi == NULL)
{ fprintf(stderr,"Greska: malloc()!\n");
exit(EXIT_FAILURE);
}
novi->broj = b;
novi->levo = NULL;
novi->desno = NULL;
return novi;
}
23
/* FUNKCIJA DODAJE NOV CVOR (BROJ 5)
U STABLO */
24
/* Funkcija dodaje nov cvor u stablo */
Cvor* dodaj_u_stablo(Cvor* koren, int broj)
{
if( koren == NULL) return napravi_cvor(broj);
/* Brojeve smestamo u uredjeno binarno stablo,
pa ako je broj koji ubacujemo manji od broja koji je u korenu */
if( broj < koren->broj)
/* dodajemo u levo podstablo */
koren->levo = dodaj_u_stablo(koren->levo, broj);
/* ako je broj veci ili jednak od broja koji je u korenu stabla,
dodajemo nov cvor desno od korena */
else
koren->desno = dodaj_u_stablo(koren->desno, broj);
return koren; }
25
/* FUNKCIJA TRAZI CEO BROJ U STABLU...*/
26
/* Funkcija trazi ceo broj u stablu.
Ako ga nadje vraca pokazivac na cvor sa trazenim brojem.
Ukoliko ne nadje vraca NULL pokazivac. */
Cvor* pretrazi_stablo(Cvor* koren, int n)
{ /* izlaz iz rekurzije*/
if(koren == NULL)
return NULL;
if(koren->broj == n)
return koren;
if( koren->broj > n)
return pretrazi_stablo(koren->levo, n);
else
return pretrazi_stablo(koren->desno, n);
}
27
/* FUNKCIJA NALAZI NAJMANJI ELEMENT
U BINARNOM STABLU */
28
/* Funkcija nalazi najmanji element u binarnom stablu
pretrage. Vraca pokazivac na cvor sa najmanjim brojem.
U slucaju neuspeha i praznog stabla vraca NULL. */
Cvor* pronadji_najmanji(Cvor* koren)
{
if(koren == NULL)
return NULL;
if(koren->levo == NULL)
return koren;
return pronadji_najmanji(koren->levo);
}
29
/* Funkcija nalazi najveci element u binarnom
stablu pretrage. Vraca pokazivac na cvor sa
najvecim brojem. U slucaju neuspeha i praznog
stabla vraca NULL. */
Cvor* pronadji_najveci(Cvor* koren)
{
if(koren == NULL)
return NULL;
if(koren->desno == NULL)
return koren;
return pronadji_najveci(koren->desno);
}
30
/* FUNKCIJA BRISE ELEMENT IZ STABLA
CIJI JE BROJ JEDNAK BROJU N. */
Ako je čvor koji treba obrisati:
1. LIST – brisanje je trivijalno.
2. NEMA LEVE (DESNE) DECE – zameniti ga sa
postojećom decom, pa obristati, kao da je list.
3. IMA OBA DETETA – pronaći najmanji element u
desnom podstablu i zameniti ga sa elementom koji
treba obristati, a potom njega obrisati kao 1. ili 2..
31
2. Obriši 5.
3. Obriši 2.
32
/* Funkcija brise element iz stabla ciji je broj jednak broju n.
Funkcija vraca koren stabla koji moze biti promenjen u
funkciji. */
Cvor* obrisi_element(Cvor* koren, int n)
{ Cvor *pomocni = NULL;
/* Izlaz iz rekurzije:
ako je stablo prazno, ono ostaje prazno i nakon brisanja */
if (koren == NULL)
return NULL;
33
/* Ako je vrednost broja veca od vrednosti korena,
tada se broj eventualno nalazi u desnom podstablu,
pa treba rekurzivno primeniti postupak na desno
podstablo. Koren ovako modifikovanog stabla je
nepromenjen, pa vracamo stari koren */
if (koren->broj < n)
{
koren->desno = obrisi_element(koren->desno, n);
return koren;
}
34
/* Ako je vrednost broja manja od vrednosti korena,
tada se broj eventualno nalazi u levom podstablu, pa
treba rekurzivno primeniti postupak na levo
podstablo. Koren ovako modifikovanog stabla je
nepromenjen, pa vracamo stari koren */
if (koren->broj > n)
{
koren->levo = obrisi_element(koren->levo, n);
return koren;
}
/* Slede podslucajevi vezani za slucaj kada je
vrednost korena jednaka broju koji se brise
(tj. slucaj kada treba obrisati koren) */ 35
/* Ako koren nema sinova, tada se on prosto brise, i
rezultat je prazno stablo (vracamo NULL) */
if (koren->levo == NULL && koren->desno == NULL)
{
free(koren);
return NULL;
}
36
/* Ako koren ima samo levog sina,
tada se brisanje vrsi tako sto obrisemo koren,
a novi koren postaje levi sin */
if (koren->levo != NULL && koren->desno == NULL)
{
pomocni = koren->levo;
free(koren);
return pomocni;
}
37
/* Ako koren ima samo desnog sina,
tada se brisanje vrsi tako sto obrisemo koren,
a novi koren postaje desni sin */
if (koren->desno != NULL && koren->levo == NULL)
{
pomocni = koren->desno;
free(koren);
return pomocni;
}
38
/* Slucaj kada koren ima oba sina.
U tom slucaju se brisanje vrsi na sledeci nacin:
Najpre se potrazi sledbenik korena (u smislu poretka) u stablu.
To je upravo po vrednosti najmanji cvor u desnom podstablu.
On se moze pronaci npr. funkcijom pronadji_najmanji().
Nakon toga se u koren smesti vrednost tog cvora,
a u taj cvor se smesti vrednost korena (tj. broj koji se brise).
Onda se prosto rekurzivno pozove funkcija za brisanje na desno
podstablo.
S obzirom da u njemu treba obrisati najmanji element,
a on definitivno ima najvise jednog potomka, jasno je da ce to
brisanje biti obavljeno na jedan od nacina koji je gore opisan. */
pomocni = pronadji_najmanji(koren->desno);
koren->broj = pomocni->broj;
pomocni->broj = n;
koren->desno = obrisi_element(koren->desno, n);
return koren;
}
39
ISPIS STABLA
LKD: 1,2,3,4,5,6,7,8,9,10,11
KLD: 6,2,1,4,3,5,8,7,10,9,11
LDK: 1,3,5,4,2,7,9,11,10,8,6
40
/* Funkcija ispisuje stablo u infiksnoj notaciji
(Levo - Koren - Desno )*/
void ispisi_drvo_infixno(Cvor* koren)
{ if(koren != NULL)
{ ispisi_drvo_infixno(koren->levo);
/* Prvo ispisujemo sve cvorove levo od korena */
printf("%d ", koren->broj);
/* ispisujemo broj u korenu */
ispisi_drvo_infixno(koren->desno);
/* Na kraju ispisujemo desno podstablo */
}
}
41
/* Funkcija ispisuje stablo prefiksno
(Koren - Levo - Desno )*/
void ispisi_drvo_prefixno(Cvor* koren)
{ if(koren != NULL)
{ printf("%d ", koren->broj);
/* ispisujemo broj u korenu */
ispisi_drvo_prefixno(koren->levo);
/* Prvo ispisujemo sve cvorove levo od korena */
ispisi_drvo_prefixno(koren->desno);
/* Na kraju ispisujemo desno podstablo */
}
}
42
/* Funkcija ispisuje stablo postfiksno
(Levo - Desno - Koren)*/
void ispisi_drvo_postfixno(Cvor* koren)
{ if(koren != NULL)
{
ispisi_drvo_postfixno(koren->levo);
/* Prvo ispisujemo sve cvorove levo od korena */
ispisi_drvo_postfixno(koren->desno);
/* Na kraju ispisujemo desno podstablo */
printf("%d ", koren->broj);
/* ispisujemo broj u korenu */
}
}
43
/* Oslobadjamo dinamicki alociran prostor za stablo */
void oslobodi_stablo(Cvor* koren)
{
/* rekurzivno oslobadjamo najpre levo,
a onda i desno podstablo*/
if( koren->levo ) oslobodi_stablo(koren->levo);
if( koren->desno) oslobodi_stablo(koren->desno);
free(koren);
}
... test program ... 44
STABLA V2.
/* NAPOMENA: Ova verzija programa ukoliko se
dogodi greska pri alociranju prostora za nov
cvor sa funkcijom malloc() osim sto prijavi gresku i
prekine program, korektno oslobadja stablo. */
#include <stdio.h>
#include <stdlib.h>
/* struktura kojom se predstavlja cvor drveta */
typedef struct dcvor{
int broj;
struct dcvor* levo, *desno;
} Cvor;
45
/* Funkcija alocira prostor za novi cvor drveta,
inicijalizuje polja strukture i vraca pokazivac na nov
cvor, tj. NULL ako je bilo greske pri alokaciji. */
Cvor* napravi_cvor(int b )
{ Cvor* novi = (Cvor*) malloc(sizeof(Cvor));
if( novi == NULL)
return NULL;
novi->broj = b;
novi->levo = NULL;
novi->desno = NULL;
return novi;
}
46
/* Oslobadjamo dinamicki alociran prostor za stablo */
Cvor* oslobodi_stablo(Cvor* koren)
{
if(koren == NULL)
return NULL;
/* Stablo nije prazno i rekurzivno oslobadjamo najpre levo,
a onda i desno podstablo*/
koren->levo = oslobodi_stablo(koren->levo);
koren->desno = oslobodi_stablo(koren->desno);
/* i tek onda mozemo da oslobodimo koren */
free(koren);
/* sad je stablo prazno i vracamo NULL */
return NULL;
} 47
/* Funkcija dodaje nov cvor u stablo */
Cvor* dodaj_u_stablo(Cvor* koren, int broj)
{
if( koren == NULL)
return napravi_cvor(broj);
/* Brojeve smestamo u uredjeno binarno stablo, pa ako je
broj koji ubacujemo manji od broja koji je u korenu */
if( broj < koren->broj)
/* dodajemo u levo podstablo */
{
koren->levo = dodaj_u_stablo(koren->levo, broj);
48
/* Ako se dogodila greska pri alokaciji i treba
osloboditi celo stablo.*/
if(koren->levo == NULL )
{
koren = oslobodi_stablo(koren);
/* vracamo NULL kao signal gornjem rekurzivnom
pozivu da je bilo greske i podstablo je oslobodjeno. */
return NULL;
}
}
49
/* ako je broj manji ili jednak od broja koji je u korenu
stabla, dodajemo nov cvor desno od korena */
else {
koren->desno = dodaj_u_stablo(koren->desno, broj);
/* Ako se dogodila greska pri alokaciji i treba osloboditi celo
stablo.*/
if(koren->desno == NULL )
{
koren = oslobodi_stablo(koren);
/* vracamo NULL kao signal gornjem rekurzivnom pozivu
da je bilo greske i podstablo je oslobodjeno. */
return NULL;
}
}
return koren;
}
50
/* Funkcija trazi ceo broj u stablu, ako ga nadje vraca
pokazivac na cvor sa trazenim brojem.
Ukoliko ne nadje vraca NULL pokazivac. */
Cvor* pretrazi_stablo(Cvor* koren, int n)
{ /* izlaz iz rekurzije*/
if(koren == NULL)
return NULL;
if(koren->broj == n)
return koren;
if( koren->broj > n)
return pretrazi_stablo(koren->levo, n);
else
return pretrazi_stablo(koren->desno, n);
}
51
/* Funkcija nalazi najmanji element u binarnom
stablu pretrage.
Vraca pokazivac na cvor sa najmanjim brojem.
U slucaju neuspeha i praznog stabla vraca NULL. */
Cvor* pronadji_najmanji(Cvor* koren)
{
if(koren == NULL)
return NULL;
if(koren->levo == NULL)
return koren;
return pronadji_najmanji(koren->levo);
}
52
/* Funkcija nalazi najveci element u binarnom
stablu pretrage.
Vraca pokazivac na cvor sa najvecim brojem.
U slucaju neuspeha i praznog stabla vraca NULL. */
Cvor* pronadji_najveci(Cvor* koren)
{
if(koren == NULL)
return NULL;
if(koren->desno == NULL)
return koren;
return pronadji_najveci(koren->desno);
}
53
/* Funkcija brise element iz stabla ciji je broj
upravo jednak broju n.
Funkcija vraca koren stabla koji moze biti
promenjen u funkciji. */
Cvor* obrisi_element(Cvor* koren, int n)
{ Cvor *pomocni = NULL;
/* Izlaz iz rekurzije: ako je stablo prazno, ono
ostaje prazno i nakon brisanja */
if (koren == NULL)
return NULL;
54
/* Ako je vrednost broja veca od vrednosti korena,
tada se broj eventualno nalazi u desnom podstablu,
pa treba rekurzivno primeniti postupak na desno
podstablo. Koren ovako modifikovanog stabla je
nepromenjen, pa vracamo stari koren */
if (koren->broj < n)
{
koren->desno = obrisi_element(koren->desno, n);
return koren;
}
55
/* Ako je vrednost broja manja od vrednosti korena,
tada se broj eventualno nalazi u levom podstablu,
pa treba rekurzivno primeniti postupak na levo
podstablo. Koren ovako modifikovanog stabla je
nepromenjen, pa vracamo stari koren */
if (koren->broj > n)
{
koren->levo = obrisi_element(koren->levo, n);
return koren;
}
56
/* Slede podslucajevi vezani za slucaj kada je vrednost
korena jednaka broju koji se brise (tj. slucaj kada treba
obrisati koren) */
/* Ako koren nema sinova, tada se on prosto brise, i
rezultat je prazno stablo (vracamo NULL) */
if (koren->levo == NULL && koren->desno == NULL)
{
free(koren);
return NULL;
}
57
/* Ako koren ima samo levog sina, tada se brisanje
vrsi tako sto obrisemo koren, a novi koren postaje
levi sin */
if (koren->levo != NULL && koren->desno == NULL)
{
pomocni = koren->levo;
free(koren);
return pomocni;
}
58
/* Ako koren ima samo desnog sina, tada se brisanje vrsi
tako sto obrisemo koren, a novi koren postaje desni sin
*/
if (koren->desno != NULL && koren->levo == NULL)
{
pomocni = koren->desno;
free(koren);
return pomocni;
}
59
/* Slucaj kada koren ima oba sina.
U tom slucaju se brisanje vrsi na sledeci nacin:
Najpre se potrazi sledbenik korena (u smislu poretka) u stablu.
To je upravo po vrednosti najmanji cvor u desnom podstablu.
On se moze pronaci npr. funkcijom pronadji_najmanji().
Nakon toga se u koren smesti vrednost tog cvora,
a u taj cvor se smesti vrednost korena (tj. broj koji se brise).
Onda se prosto rekurzivno pozove funkcija za brisanje na desno
podstablo.
S obzirom da u njemu treba obrisati najmanji element,
a on definitivno ima najvise jednog potomka, jasno je da ce to
brisanje biti obavljeno na jedan od nacina koji je gore opisan. */
pomocni = pronadji_najmanji(koren->desno);
koren->broj = pomocni->broj;
pomocni->broj = n;
koren->desno = obrisi_element(koren->desno, n);
return koren;
}
60
/* Funkcija ispisuje stablo u infiksnoj notaciji
(Levo - Koren - Desno )*/
void ispisi_drvo_infixno(Cvor* koren)
{ if(koren != NULL)
{ ispisi_drvo_infixno(koren->levo);
/* Prvo ispisujemo sve cvorove levo od korena */
printf("%d ", koren->broj);
/* ispisujemo broj u korenu */
ispisi_drvo_infixno(koren->desno);
/* Na kraju ispisujemo desno podstablo */
}
}
61
/* Funkcija ispisuje stablo prefiksno
(Koren - Levo - Desno )*/
void ispisi_drvo_prefixno(Cvor* koren)
{ if(koren != NULL)
{ printf("%d ", koren->broj);
/* ispisujemo broj u korenu */
ispisi_drvo_prefixno(koren->levo);
/* Prvo ispisujemo sve cvorove levo od korena */
ispisi_drvo_prefixno(koren->desno);
/* Na kraju ispisujemo desno podstablo */
}
}
62
/* Funkcija ispisuje stablo postfiksno
(Levo - Desno - Koren)*/
void ispisi_drvo_postfixno(Cvor* koren)
{ if(koren != NULL)
{
ispisi_drvo_postfixno(koren->levo);
/* Prvo ispisujemo sve cvorove levo od korena */
ispisi_drvo_postfixno(koren->desno);
/* Na kraju ispisujemo desno podstablo */
printf("%d ", koren->broj);
/* ispisujemo broj u korenu */
}
}
63
int main()
{
Cvor* koren = NULL; /* Napomena: Prazno stablo! */
int n;
Cvor* trazeni;
printf("Unosite cele brojeve! --- CTRL+D za prekid
unosenja!\n");
while( scanf("%d",&n) != EOF)
{ koren=dodaj_u_stablo(koren,n);
printf(" Stablo ( L-K-D) : ");
ispisi_drvo_infixno(koren);
putchar('\n');
} 64
printf("\nUneto drvo u infixnom obilasku (L-K-D): ");
ispisi_drvo_infixno(koren);
putchar('\n');
printf("Uneto drvo u prefixnom obilasku (K-L-D): ");
ispisi_drvo_prefixno(koren);
putchar('\n');
printf("Uneto drvo u postfixnom obilasku (L-D-K): ");
ispisi_drvo_postfixno(koren);
putchar('\n');
printf("Koji se to broj trazi u stablu? \t");
scanf("%d",&n); 65
trazeni = pretrazi_stablo(koren,n);
if(trazeni == NULL)
printf("Element %d nije u stablu!\n",n);
else printf("Element %d se nalazi u
stablu!!!\n", trazeni->broj);
printf("\nNajveci element u stablu je %d, a
najmanji je %d.\n", pronadji_najveci(koren)->broj ,
pronadji_najmanji(koren)->broj);
koren = oslobodi_stablo(koren);
return 0;
} 66