66
PROGRAMIRANJE 2 VEŽBE REDOVI. BINARNA STABLA. Staša Vujičić Stanković

REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

PROGRAMIRANJE 2

VEŽBE

REDOVI. BINARNA STABLA.

Staša Vujičić Stanković

Page 2: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 3: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

3

Page 4: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 5: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 6: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 7: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 8: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

#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

Page 9: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 10: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 11: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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);

}

Page 12: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

if (*kraj != NULL) {

(*kraj)->sledeci = novi;

*kraj = novi;

} else {

/* ako je red prazan */

*pocetak = novi;

*kraj = novi;

}

}

12

Page 13: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 14: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 15: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* Funkcija prikazuje red */

void prikazi_red(Cvor * pocetak)

{

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

printf("%s, ", pocetak->ime_fajla);

printf("\n");

}

15

Page 16: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 17: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 18: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 19: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 20: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 21: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 22: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 23: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 24: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* FUNKCIJA DODAJE NOV CVOR (BROJ 5)

U STABLO */

24

Page 25: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 26: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* FUNKCIJA TRAZI CEO BROJ U STABLU...*/

26

Page 27: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 28: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* FUNKCIJA NALAZI NAJMANJI ELEMENT

U BINARNOM STABLU */

28

Page 29: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 30: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 31: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 32: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

2. Obriši 5.

3. Obriši 2.

32

Page 33: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 34: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 35: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 36: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 37: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 38: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 39: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 40: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 41: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 42: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 43: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 44: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 45: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 46: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 47: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 48: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 49: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 50: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 51: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 52: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 53: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 54: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 55: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 56: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 57: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 58: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 59: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 60: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 61: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 62: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 63: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

/* 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

Page 64: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 65: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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

Page 66: REDOVI. BINARNA STABLApoincare.matf.bg.ac.rs/~stasa/P2/Cas 12.pdf · Uređeno stablo je stablo u kome su deca svakog čvora uređena u nekom poretku. Binarno uređeno stablo je uređeno

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