14
Strukture podataka i algoritmi 2 dr Boban Stojanović 1 Stabla Uvod Stabla se koriste za predstavljanje hijerarhijske strukture neke kolekcije podataka. Stablo se sastoji od jednog ili više čvorova koji zadovoljavaju sledeće uslove: 1. Postoji jedan čvor koji predstavlja koren stabla i 2. Ostali čvorovi su podeljeni u n disjunktnih skupova čvorova, tako da svaki skup predstavlja stablo. Na Slici ### je prikazan primer stabla: A B C D G H I E F Slika ### Šematski prikaz stabla Struktura prikazana na prethodnoj slici je stablo iz razloga što je to skup čvorova {A, B, C, D, E, F, G, H, I}, pri čemu je čvor A koren stabla, a ostali čvorovi su podeljeni u tri disjunktna skupa {B, G, H, I}, {C, E, F} i {D}. Svaki od ova tri skupa je takođe stablo, zato što zadovoljava oba uslova navedena u definiciji. Struktura prikazana na Slici ### nije stablo, zato što činjenica da je čvor E podeljen onemogućava razdvajanje čvorova od B do I u disjunktne skupove. A B C D G H I E F Slika ### Šematski prikaz strukture koja nije stablo Stepen čvora stabla Stepen čvora stabla je broj podstabala kojima je ovaj čvor koren. Drugim rečima, stepen je broj naslednika (dece) čvora. Ukoliko je stepen čvora nula, takav čvor nazivamo list stabla. Stepen stabla Stepen stabla se definiše kao maksimum stepena svih čvorova stabla. Nivo čvora Nivo čvora definišemo tako što uzimamo da je nivo korena stabla jednak 1, a zatim uvećavamo ovaj broj za jedan pri svakom skoku od korena ka podstablima. Tako, nivo svih naslednika korena će biti 2, nivo njihovih naslednika 3 itd. Dubinu stabla zatim definišemo kao maksimalni nivo čvora u stablu.

Stabla

  • Upload
    davor

  • View
    7

  • Download
    1

Embed Size (px)

DESCRIPTION

Stabla

Citation preview

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    1

    Stabla

    Uvod Stabla se koriste za predstavljanje hijerarhijske strukture neke kolekcije podataka. Stablo se sastoji od jednog ili vie vorova koji zadovoljavaju sledee uslove:

    1. Postoji jedan vor koji predstavlja koren stabla i

    2. Ostali vorovi su podeljeni u n disjunktnih skupova vorova, tako da svaki skup predstavlja stablo.

    Na Slici ### je prikazan primer stabla:

    A

    B C D

    G H I E F

    Slika ### ematski prikaz stabla

    Struktura prikazana na prethodnoj slici je stablo iz razloga to je to skup vorova {A, B, C, D, E, F, G, H, I}, pri emu je vor A koren stabla, a ostali vorovi su podeljeni u tri disjunktna skupa {B, G, H, I}, {C, E, F} i {D}. Svaki od ova tri skupa je takoe stablo, zato to zadovoljava oba uslova navedena u definiciji.

    Struktura prikazana na Slici ### nije stablo, zato to injenica da je vor E podeljen onemoguava razdvajanje vorova od B do I u disjunktne skupove.

    A

    B C D

    G H I E F

    Slika ### ematski prikaz strukture koja nije stablo

    Stepen vora stabla

    Stepen vora stabla je broj podstabala kojima je ovaj vor koren. Drugim reima, stepen je broj naslednika (dece) vora. Ukoliko je stepen vora nula, takav vor nazivamo list stabla.

    Stepen stabla

    Stepen stabla se definie kao maksimum stepena svih vorova stabla.

    Nivo vora

    Nivo vora definiemo tako to uzimamo da je nivo korena stabla jednak 1, a zatim uveavamo ovaj broj za jedan pri svakom skoku od korena ka podstablima. Tako, nivo svih naslednika korena e biti 2, nivo njihovih naslednika 3 itd. Dubinu stabla zatim definiemo kao maksimalni nivo vora u stablu.

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    2

    Binarno stablo Binarno stablo je specijalni sluaj stabla u kome ni jedan vor nema stepen vei od 2. To praktino znai da svaki vor ima najvie dva naslednika. Dakle, binarno stablo je skup od jednog ili vie vorova takvih da:

    1. Postoji jedan vor koji je koren stabla i

    2. Preostali vorovi su podeljeni u dva disjunktna skupa, tako da svaki skup predstavlja binarno stablo. Ova dva skupa se nazivaju levo i desno podstablo.

    Na Slici ### je prikazano binarno stablo:

    Slika ### Binarno stablo

    Za binarno stablo vai:

    1. Maksimalni broj vorova na i-tom nivou je 12i

    2. Ako je k dubina binarnog stabla, onda je maksimalan broj vorova koje stablo moe da ima je 1 2 02 1 2 2 ... 2k k k = + + +

    Napomenimo da mogu postojati i iskoena stabla, kao to je to prikazano na Slici ###:

    A

    B

    C

    Iskoeno u levo Iskoeno u desno

    Slika ### Iskoena binarna stabla

    Puno binarno stablo je binarno stablo dubine k koje sadri 2 1k vorova. Ukoliko je broj vorova manji od 2 1k , binarno stablo je nepotpuno. Primer punog binarnog stabla je prikazan na Slici ###:

    Slika ### Puno binarno stablo

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    3

    Na prethodnoj slici smo vorove stabla oznaili brojevima od 1 do 7. Ukoliko je binarno stablo puno njegovi vorovi se mogu numerisati brojevima od 1 do 2 1k tako to bi se poelo od korena, a zatim numerisao jedan po jedan nivo sa leva na desno.

    Kompletno binarno stablo dubine k je stablo sa n vorova u kome bi se ovih n vorova moglo numerisati brojevima od 1 do n, kao kada bi to bilo prvih n vorova u punom stablu dubine k.

    Na Slici ### je prikazano kompletno binarno stablo dubine k=3:

    1

    2 3

    54

    Slika ### Kompletno binarno stablo

    Predstavljanje binarnog stabla Binarno stablo moe biti predstavljeno korienjem niza tako to bi vrednost u svakom voru bila pridruena elementu niza sa indeksom koji je jednak numeraciji tog vora u odgovarajuem punom binarnom stablu. Meutim, s obzirom na ozbiljne nedostatke, neemo detaljnije opisivati ovaj nain predstavljanja binarnog stabla. Umesto toga, pokazaemo kako je mogue predstaviti binarno stablo korienjem povezanih struktura.

    Binarno stablo je mogue veoma efikasno predstaviti korienjem povezanih struktura, tako to bi svaki vor bio predstavljen strukturom sa tri promenljive: podatak koji se uva, pokaziva na levo podstablo i pokaziva na desno podstablo, kao to je prikazano na Slici ###:

    Slika ### Predstavljanje binarnog stabla korienjem povezanih struktura

    Ukoliko vor nema nekog od naslednika, pokaziva na tog naslednika bi u tom sluaju bio NULL.

    Deklaracija strukture za predstavljanje vora binarnog stabla u programskom jeziku C bi mogla da izgleda ovako:

    structcvor{ intpodatak; structcvor*levi,*desni;};

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    4

    Obilazak binarnog stabla Pod obilaskom binarnog stabla podrazumevamo prolazak kroz sve njegove vorove odreenim redosledom, pri emu je istovremeno mogue izvriti i odreenu operaciju nad podacima koji su u njima zapisani.

    U zavisnosti od redosleda obrade odreenog vora i njegovog levog i desnog podstabla, obilazak stabla se moe izvriti na est naina:

    Skraenica Opis LPD obilazak levog podstabla, obrada podatka, obilazak desnog podstabla LDP obilazak levog podstabla, obilazak desnog podstabla, obrada podatka PLD obrada podatka, obilazak levog podstabla, obilazak desnog podstabla PDL obrada podatka, obilazak desnog podstabla, obilazak levog podstabla DLP obilazak desnog podstabla, obilazak levog podstabla, obrada podatka DPL obilazak desnog podstabla, obrada podatka, obilazak levog podstabla

    pri emu

    L oznaava obilazak levog podstabla,

    D oznaava obilazak desnog podstabla,

    P oznaava obradu podatka u trenutnom voru.

    Tako, na primer LPD oznaava redosled u kome kreemo od korena, obilazimo levo podstablo, obraujemo podatak u korenu i na kraju obilazimo desno podstablo. S obzirom na to da su levo i desno podstablo takoe binarna stabla, potpuno ista procedura se koristi i za njihov obilazak.

    Redosled LPD se naziva jo i inorder, redosled LDP postorder, a redosled PLD preorder. Ostala tri redosleda se nikada ne koriste. Ukoliko prilikom obilaska stabla tampamo podatke koji se nalaze u vorovima, u zavisnosti od toga da li koristimo inorder, preorder ili postorder, dobijamo rezultate kao to je prikazano na Slici ###:

    Inorder: D,B,H,E,I,A,F,C,G

    Preorder: A,B,D,E,H,I,C,F,G

    Postorder: D,H,I,E,B,F,G,C,A

    Slika ### Redosled obilaska binarnog stabla

    Tipian primer korienja binarnog stabla je predstavljanje aritmetikih izraza.

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    5

    Inorder: a+b*c+d*e

    Preorder: ++a*bc*de

    Postorder: abc*+de*+

    Slika ### Aritmetiki izraz predstavljen binarnim stablom

    Binarno stablo za pretraivanje Binarno stablo za pretraivanje je binarno stablo koje ima sledee karakteristike:

    1. vorovima binarnog stabla su pridruene vrednosti po kojima se obavlja pretraivanje.

    2. Za bilo koji vor vai da svi vorovi u levom podstablu imaju vrednost manju od njega, a svi vorovi u desnom podstablu imaju vrednost veu od njega. I levo i desno stablo su takoe binarna stabla za pretraivanje.

    Primer binarnog stabla za pretraivanje je prikazan na Slici ###

    Slika ### Binarno stablo za pretraivanje

    Binarno stablo za pretraivanje je u osnovi binarno stablo, tako da se moe obii u inorder, preorder ili postorder redosledu. Ukoliko binarno stablo za pretraivanje obiemo u inorder redosledu i pri tome odtampamo vrednosti u vorovima, dobiemo vrednosti sortirane u rastuem redosledu.

    Binarno stablo za pretraivanje je veoma vana struktura podataka. Posmatrajmo, na primer, problem pretraivanja niza. Ukoliko je niz sortiran, pretraivanje moemo znatno ubrzati korienjem binarnog pretraivanja. Meutim, ukoliko elimo da izvrimo promene u nizu kao to su dodavanje i brisanje elementa, to e zahtevati pomeranje odreenog broja elemenata svaki put. Ovaj problem moemo reiti korienjem povezanih lista, zato to one omoguavaju dodavanje i brisanje elemenata vrlo jednostavnim premetanjem nekoliko pokazivaa. Meutim, problem sa povezanim listama je to to one ne omoguavaju direktan pristup pojedinim elementima, ve samo sekvencijalno kretanje kroz listu, element po element. Reenje ovih problema lei upravo u binarnim stablima. Ukoliko se elementi ureenog niza ili liste smeste u vorove binarnog stabla za pretraivanje, nalaenje odgovarajueg kljua u binarnom stablu zahteva (log )O n koraka.

    Kreiranje binarnog stabla za pretraivanje Pretpostavimo da svaki vor binarnog stabla sadri celobrojni podatak, kao i pokazivae na levo i desno podstablo. U tom sluaju struktura koja opisuje vor binarnog stabla bi mogla da izgleda ovako:

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    6

    structcvor{ intpodatak; structcvor*levi,*desni;};

    U nastavku je dat kompletan program za kreiranje binarnog stabla za pretraivanje:

    #include#includestructcvor{ intpodatak; structcvor*levi,*desni;};/*funkcijazadodavanjenovogcvoraubinarnostablozapretrazivanje*/structcvor*dodaj(structcvor*p,intvrednost){ structcvor*pom1,*pom2,*novi; /*kreiranjenovogcvora*/ novi=(structcvor*)malloc(sizeof(structcvor)); if(novi==NULL) { printf("Greskaprialociranjumemorije.\n"); exit(0); } novi>podatak=vrednost; novi>levi=novi>desni=NULL; if(p==NULL) { p=novi; } else { /*prolazakkrozstablokakobisepronasaocvorcijecedetebitinovicvor*/ pom1=p; while(pom1!=NULL) { pom2=pom1; if(vrednostpodatak) pom1=pom1>levi; else pom1=pom1>desni; } if(vrednostpodatak) pom2>levi=novi; /*dodavanjenovogcvorakaolevogdeteta*/ else pom2>desni=novi; /*dodavanjenovogcvorakaodesnogdeteta*/ } return(p);}/*funkcijazastampanjebinarnogstablauinorderredosledu*/voidstampaj_inorder(structcvor*p){ if(p!=NULL) { stampaj_inorder(p>levi); printf("%d\t",p>podatak); stampaj_inorder(p>desni); }}voidmain(){ structcvor*koren=NULL; inti,n,x;

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    7

    printf("Unesitebrojcvorova:\n"); scanf("%d",&n); for(i=0;ipodatak==kljuc)return(pom); else if(pom>podatak>kljuc) pom=pom>levi; else

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    8

    pom=pom>desni; } return(NULL);}

    Odreivanje broja vorova u binarnom stablu Broj vorova bilo kog stabla koje nije list jednak je zbiru broja vorova u njegovom levom i desnom podstablu, koji se uveava za jedan kako bi se uraunao i koren stabla. Ukoliko je stablo list (nema potomaka), onda je broj vorova u njemu jednak jedan. Ovaj opis ukazuje na potrebu rekurzivnog prolaska kroz stablo sve dok se ne doe do njegovih listova.

    Naredna rekurzivna funkcija vri prebrojavanje vorova u binarnom stablu.

    structcvor{ intpodatak; structcvor*levi,*desni;}; ...intbroj(structcvor*p){ if(p==NULL) return(0); else if(p>levi==NULL&&p>desni==NULL) return(1); else return(1+(broj(p>levi)+broj(p>desni)));}

    Zamena mesta levim i desnim podstablima Elegantan metod za zamenu mesta levim i desnim podstablima unutar binarnog stabla je korienje rekurzivnog algoritma. Funkcija zamenjuje mesta levom i desnom podstablu, a zatim na njima rekurzivno primenjuje isti postupak.

    structcvor{ intpodatak; structcvor*levi,*desni;}; ...voidzameni(structcvor*p){ structcvor*pom; if(p!=NULL) { pom=p>levi; p>levi=p>desni; p>desni=pom; zameni(p>levi); zameni(p>desni); }}

    Primenom ovog algoritma na binarno stablo za pretraivanje, koje bi pri inorder tampanju dalo rastui niz, dobilo bi se binarno stablo koje bi pri inorder tampanju dalo opadajui niz.

    Brisanje vora iz binarnog stabla za pretraivanje Oznaimo pokaziva na vor koji elimo da obriemo sa x (skraeno: vor x), a pokaziva na vor koji je njegov roditelj sa y. Nakon brisanja vora x, potrebno je izvriti reorganizaciju njegovih potomaka kako bi oni i dalje formirali binarno stablo za pretraivanje, a zatim novoformirano podstablo povezati na

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    9

    odgovarajui nain sa vorom y, u zavisnosti od toga da li je vor x bio levi ili desni potomak vora y. U sluaju da je vor x bio koren stabla, onda podstablo formirano od njegovih potomaka postaje novi koren. Oznaimo pokaziva na podstablo formirano od potomaka vora x sa q.

    Brisanje vora koji ima dva potomka

    Posmatrajmo binarno stablo prikazano na Slici ###:

    Slika ### Binarno stablo pre brisanja vora na koji pokazuje x

    Korienjem pomonog pokazivaa pom, prolazimo kroz levo podstablo vora x, kako bismo pronali njegov desni list, a zatim postavljamo desni pokaziva ovog lista da pokazuje na desno podstablo vora x, kao to je pokazano na Slici ###. Nakon toga, pokaziva q se postavlja da pokazuje na levo podstablo vora x, a vor x se brie iz memorije. Ukoliko pokaziva y nije NULL, ostaje samo da se pokaziva q postavi za odgovarajueg potomka vora y. Ako pokaziva na vor y jeste NULL (obrisan je koren), onda novi koren postaje pokaziva q.

    Slika ### Binarno stablo nakon brisanja vora na koji pokazuje x

    Drugi nain brisanja vora je da se prolazi kroz desno podstablo vora x kako bi se pronaao njegov levi list, a zatim se levi pokaziva tog lista postavlja da pokazuje na levo podstablo vora x, kao to je prikazano na

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    10

    Slici ###. Naravno, na kraju je potrebno obrisati vor x iz memorije. Nakon toga, pokaziva q se postavlja da pokazuje na desno podstablo vora x, a vor x se brie iz memorije. Ukoliko pokaziva y nije NULL, ostaje samo da se pokaziva q postavi za odgovarajueg potomka vora y. Ako pokaziva na vor y jeste NULL (obrisan je koren), onda novi koren postaje pokaziva q.

    Slika ### Binarno stablo nakon brisanja vora na koji pokazuje x

    Brisanje vora koji ima jednog potomka

    Posmatrajmo binarno stablo prikazano na Slici ###:

    Slika ### Binarno stablo pre brisanja vora na koji pokazuje x

    Ukoliko elimo da obriemo vor x, dovoljno je da postavimo pokaziva q da pokazuje na podstablo vora x koje postoji, a zatim iz memorije obriemo vor x, kao to je prikazano na Slici ###. Ukoliko pokaziva y nije NULL, ostaje samo da se pokaziva q postavi za odgovarajueg potomka vora y. Ako pokaziva na vor y jeste NULL (obrisan je koren), onda novi koren postaje pokaziva q.

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    11

    Slika ### Binarno stablo nakon brisanja vora na koji pokazuje x

    Brisanje vora koji nema ni jednog potomka

    Posmatrajmo binarno stablo na Slici ###:

    Slika ### Binarno stablo pre brisanja vora na koji pokazuje x

    Da bismo obrisali vor x iz binarnog stabla, potrebno je samo da pokazivau q dodelimo NULL, a zatim, ukoliko pokaziva y nije NULL, ostaje samo da se pokaziva q postavi za odgovarajueg potomka vora y. Ako pokaziva na vor y jeste NULL (obrisan je koren), onda novi koren postaje pokaziva q.

    Slika ### Binarno stablo nakon brisanja vora na koji pokazuje x

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    12

    Primer

    #include#includestructcvor{ intpodatak; structcvor*levi,*desni;};/*Funkcijakojavracapokazivacnacvorsatrazenomvrednoscuipokazivacnanjegovogroditelja*/structcvor*pronadji(structcvor*p,intkljuc,structcvor**y){ structcvor*pom; if(p==NULL) return(NULL); pom=p; *y=NULL; while(pom!=NULL) { if(pom>data==kljuc) return(pom); else { *y=pom;/*pamcenjeroditelja*/ if(kljucdata) pom=pom>levi; else pom=pom>desni; } } return(NULL);}/*Funkcijazabrisanjecvorakojisadrzizadatuvrednost*/structcvor*obrisi(structcvor*p,intvrednost){ structcvor*x,*y,*q,*pom,; x=pronadji(p,vrednost,&y); if(x==NULL) { printf("Cvornepostoji.\n"); return(p); } if(x>levi!=NULL&&x>desni!=NULL)/*brisanjecvorakojiimaobapotomka*/ { pom=x>levi; while(pom>desni!=NULL)pom=pom>desni; pom>desni=x>desni; q=x>levi; } elseif(x>levi==NULL&&x>desni!==NULL)/*brisanjecvorakojiimasamodesnogpotomka*/ { q=x>desni; } elseif(x>levi!=NULL&&x>desni==NULL)/*brisanjecvorakojiimasamolevogpotomka*/ { q=x>levi; } elseif(x>levi==NULL&&x>desni==NULL)/*brisanjecvorakojinemanijednogpotomka*/ { q=NULL; } if(y!=NULL) { if(y>levi==x) y>levi=q; else

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    13

    y>desni=q; } else p=q; free(x); return(p);}/*funkcijazadodavanjenovogcvoraubinarnostablozapretrazivanje*/structcvor*dodaj(structcvor*p,intvrednost){ structcvor*pom1,*pom2,*novi; /*kreiranjenovogcvora*/ novi=(structcvor*)malloc(sizeof(structcvor)); if(novi==NULL) { printf("Greskaprialociranjumemorije.\n"); exit(0); } novi>podatak=vrednost; novi>levi=novi>desni=NULL; if(p==NULL) { p=novi; } else { /*prolazakkrozstablokakobisepronasaocvorcijecedetebitinovicvor*/ pom1=p; while(pom1!=NULL) { pom2=pom1; if(vrednostpodatak) pom1=pom1>levi; else pom1=pom1>desni; } if(vrednostpodatak) pom2>levi=novi; /*dodavanjenovogcvorakaolevogdeteta*/ else pom2>desni=novi; /*dodavanjenovogcvorakaodesnogdeteta*/ } return(p);}/*funkcijazastampanjebinarnogstablauinorderredosledu*/voidstampaj_inorder(structcvor*p){ if(p!=NULL) { stampaj_inorder(p>levi); printf("%d\t",p>podatak); stampaj_inorder(p>desni); }}voidmain(){ structcvor*koren=NULL; intn,i,x; printf("Unesitebrojcvorovastabla:\n"); scanf("%d",&n); for(i=0;i

  • Strukture podataka i algoritmi 2 dr Boban Stojanovi

    14

    printf("Stabloprebrisanjaje:\n"); stampaj_inorder(koren); printf("\n"); printf("Unesitevrednostkojutrebaobrisati:\n"); scanf("%d",&x); koren=obrisi(koren,n); printf("Stabloposlebrisanjaje:\n"); stampaj_inorder(koren);}