29
Pemet e Kerkimit Binar Leksion 9

Pemet e Kerkimit Binar

  • Upload
    dreama

  • View
    275

  • Download
    6

Embed Size (px)

DESCRIPTION

Pemet e Kerkimit Binar. Leksion 9. Perkufizime. Një pemë ( tree ) është një strukturë të dhënash e kapshme duke filluar nga rrënja ( root ). Çdo nyje ( node ) është ose një gjethe ( leaf ) ose një nyje e brendshme ( internal node ). - PowerPoint PPT Presentation

Citation preview

Pemet e Kerkimit Binar

Leksion 9

Perkufizime Një pemë (tree) është një strukturë të dhënash e

kapshme duke filluar nga rrënja (root). Çdo nyje (node) është ose një gjethe (leaf) ose një nyje e brendshme (internal node).

Një nyje e brendshme ka një bir (child)ose më shumë dhe quhet prindi (parent) i nyjeve bija të veta.

Të gjithë bijtë e të njëjtës nyje janë të të njëjtit brez (siblings).

Rrënja është elementi i dallueshëm fillestar ose bazë i një peme. Rrënja është i vetmi element që nuk ka prind.

Perkufizime Një nyje është një njësi reference në një strukturë të

dhënash.

Një gjethe është një element fundor i një peme. Një gjethe është një element pa bij. Ndryshe, një gjethe quhet nyje e jashtme (external node) ose nyje fundore (terminal node).

Një nyje e brendshme është një nyje peme që ka një ose më shumë bij (nyje bija). Një nyje e brendshme është një nyje peme që nuk është gjethe.

Perkufizime Një bir është një element i pemës i cili referohet

nga elementi prind. Çdo element përveç rrënjës është biri i ndonjë prindi.

Prindi i një nyjeje është nyja e pemës konceptualisht sipër ose më afër rrënjës se nyja dhe e cila ka një lidhje (link) me nyjen. Sipas përkufizimit një nyje prind është një nyje e brendshme.

Një lidhje është një referencë, shënjues (pointer) apo mënyrë kapjeje për tek një tjetër pjesë e strukturës së të dhënave. Shpesh, një adresë kujtese.Një nyje në një pemë e cila ka të njëjtin prind me një nyje tjetër quhet e të njëjtit brez me të.

Perkufizime Një pemë binare (binary tree) është një pemë

me të shumtën dy bij për çdo nyje.

Një pemë e kërkimit binar (binary search tree) është një pemë binare ku çdo nënpemë e majtë e nyjes ka çelësa më të vegjël se çelësi (key) i nyjes dhe çdo nënpemë e djathtë ka çelësa më të mëdhenj se çelësi i nyjes.

Një nënpemë është pema bijë e një nyjeje.

Një çelës është pjesa e një grupi të dhënash me anë të së cilës ai (grupi i të dhënave) renditet, indeksohet, referohet etj.

program pemet_BST;{Ky eshte nje program ne Pascal qellimi i te cilit eshte ilustrimi i pemeve te} { kerkimit binar (Binary Search Tree – BST)}constmax_lartesi_BST = 32 {lartesia maksimale e pemes BST – nje peme

BST} {mund te kete maksimalisht 2lartesia elemente} ;type{E deklarojme pemen e kerkimit binar – BST - si tip te dhenash rekursiv }{bazuar ne perkufizimin: Nje peme e kerkimit binar – BST - eshte boshe}{ose perbehet prej rrenjes, nenpemes (BST) se saj te majte dhe te nenpemes }{(BST) se saj te djathte}

tip_elementi = integer;peme = ^nyje_peme;nyje_peme = record

element : tip_elementi; lidhje : array [1..2] of peme;

end;tabele_peme =record

rrenja : peme; numri : integer;end;

varp : peme ;t : tabele_peme;

procedure inicializo (var t : tabele_peme);{kjo procedure krijon nje peme te kerkimit binar – BST-

boshe}begin {inicializo}

t.rrenja := nil;t.numri  := 0 ;

end {inicializo};

function bosh (var p : peme) : boolean;{ky funksion kthen true n.q.s. pema BST p eshte boshe

dhe false ne te kundert}begin {bosh}

bosh := p = nil;end {bosh};

procedure bredhje_pararendore (p : peme);{bredhje ne te gjithe elementet e nenpemes p – metoda pararendore

(pre-order)}begin

if not bosh(p) thenbegin

writeln (p^.element);bredhje_pararendore (p^.lidhje[1]) ;bredhje_pararendore (p^.lidhje[2]) ;

endend {bredhje_pararendore};

procedure bredhje_pasrendore (p : peme);{bredhje ne te gjithe elementet e nenpemes p – metoda pasrendore

(post-order)}begin

if not bosh(p) thenbegin

bredhje_pasrendore (p^.lidhje[1]) ;bredhje_pasrendore (p^.lidhje[2]) ;writeln (p^.element);

endend {bredhje_pasrendore};

procedure bredhje_nder_rendore (p : peme);{bredhje ne te gjithe elementet e nenpemes p – metoda nder-

rendore (in-order)}begin

if not bosh(p) thenbeginbredhje_nder_rendore (p^.lidhje[1]) ;writeln (p^.element);bredhje_nder_rendore (p^.lidhje[2]) ;

endend {bredhje_nder_rendore};

function numri (p : peme) : integer;{ky funksion kthen numrin e elementeve te nenpemes p}begin {numri}

if p = nil thennumri := 0

elsenumri := numri (p^.lidhje[1]) + 1 + numri (p^.lidhje[2]);

end {numri};

procedure lexo_BST (var p : peme; var t : tabele_peme);{shton elementet ne nje peme te tipit BST, duke u bazuar pikerisht ne } { cilesite e pemes se kerkimit binar – BST}var{ne elm ruajme elementin per tu shtuar, akoma tregon nese kemi }{ akoma elemente per shqyrtim; ugjet tregon elementi kandidat per t’u }{ shtuar ekziston ne peme apo jo; p eshte shenjuesi mbi elementin e ri }{ per tu shtuar dhe q prindi i tij (nese ka te tille) ne pemen t; drejtimi }{ tregon kahun e vendndodhjes se p (birit te q)}

elm : tip_elementi; akoma, ugjet : boolean; q : peme;drejtimi : integer;

procedure perfto (var elm : tip_elementi; var akoma : boolean);{perftojme elementin e rradhes dhe shqyrtojme nese ka akoma {elemente te tjere}

constfund = -1;

beginreadln (elm);

akoma := elm <> fundend {perfto};

begin{inicializimi}elm := 0;akoma := true;perfto (elm, akoma);while akoma do {derisa te mos kemi si input elm=-1}begin{bredhim pemen me ane te shenjuesit p duke ruajtur ne q prindin e } { p dhe tek drejtimi kahun e zbritjes ne pemen t}

q := nil;p := t.rrenja;ugjet := false;while ((p <> nil) and not(ugjet)) do

if p^.element = elm thenugjet := true {nese elementi tashme ekziston mos

bej asgje} else

beginif p^.element > elm then

drejtimi := 1else

drejtimi := 2;q := p;p := p^.lidhje[drejtimi]

end;

If not(ugjet) then begin

new (p);p^.element := elm;p^.lidhje[1] := nil;p^.lidhje[2] := nil;if q <> nil then

q^.lidhje[drejtimi] := p else

t.rrenja := p; {q=nil dmth shto ne rrenje} t.numri := t.numri +1 ;end ;

perfto (elm, akoma);end;

end {lexo_BST};

begin {MAIN}inicializo (t);p := nil;lexo_BST(p,t) ;p := t.rrenjabredhje_nder_rendore(p) ;p := t.rrenjanumri(p) ;

end {MAIN}.

5

3 8

2 6

7

4

Krahasojme 7 me 5; meqenese 7 eshte mee madhe se 5 shqyrtojme birin e djathte te 5

77 eshte me e vogel se 8 prandajshqyrtojme birin e majte te 8

77 eshte me e madhe se 6 por 6 nuk ka bir tedjathte prandaj shto 7 si bir te djathte te 6

5

3 8

2 64

7

Shtimi ne nje pemete kerkimit binar

Nje efekt anesor i metodes se zakonshme te shtimit ne nje peme te kerkimit binary (BST), sipas implementimit ne proceduren e meparshme, eshte se elementet e shtuar me vone tentojne te jene me larg nga rrenja dhe prandaj duhet me shume kohe per ti gjetur ata ne krahasim me elementet e shtuar para tyre. Nese te gjithe elementet kane te njejtat gjasa per te qene kandidate te nje kerkimi atehere ky fakt nuk eshte i rendesishem, por nese jemi ne rastet e disa modeleve te perdorimit komun ku elementet e shtuar me vone tentohen te kerkohen me shpesh se ata me te hershem (nga kendveshtrimi i shtimit ne peme) atehere kemi te bejme me nje problem jo te vogel.

Nje skeme alternative per shtimin, skeme e cila adreson

edhe problemin e siperpermendur, eshte skema e shtimit nga rrenja. Sipas ketij algoritmi, nyja e re vendoset gjithmone ne rrenje te pemes. Duke ndjekur nje seri shtimesh te tilla nyjet e futura me vone kane tendence te jene me afer rrenjes se nyjet e tjera.

Si nje perpjekje te pare per implementimin e kesaj ideje, ne mund te perpiqemi ta bejme nyjen e re si rrenje te pemes dhe ta kthejme rrenjen e vjeter si nje nga bijte e saj.

Per fat te keq, ky perafrim apo ndonje tjeter i ngjashem me te, nuk do te funksionoje sepse nuk ka garanci qe nyjet ne pemen ekzistuese kane te gjitha vlera me te medha apo me te vogla se nyja e re.

Nje perafrim qe funksionon eshte kryerja e nje shtimi konvencional si nje nyje gjethe sipas algoritmit tashme te pershkruar te shtimit dhe pastaj kryerja e nje serie rrotullimesh per ta levizur nyjen e re drejt rrenjes.

Y

X c

a b

X

Ya

b c

Një rrotullim ështënjë transformim ithjeshtë i njëpeme binare qëngjan me:

ku X dhe Y përfaqësojnë nyje dhe a, b dhe c përfaqësojnë nënpemë binare arbitrare qëmund të jenë boshe. Shigjetat vertikale (mbi Y dhe X respektivisht ne figurat majtas dhedjathtas) tregojnë se pemet BST subjekte të rrotullimit mund të jenë nënpemë të një pememë të madhe. Një rrotullim e ndryshon strukturën lokale të një peme të kërkimit binar pandryshuar renditjen e saj sipas bredhjes ndërrendore.

Rrotullimet kanë vetitë e mëposhtme:Rrotullimet ndryshojnë strukturën e një peme binare. Në veçanti, rrotullimet mundet që

shpesh, në varësi të formës së pemës, të përdoren për të ndryshuar lartësinë e një pjesetë një peme binare.

Rrotullimet ndryshojnë strukturën lokale të një peme binare. Çdo rrotullim i dhënëndikon vetëm mbi nyjen e rrotulluar dhe bijtë e saj të menjëhershëm. Paraardhësit enyjes dhe bijtë e bijve të saj ngelin të pandryshuar.

Rrotullimet nuk e ndryshojnë renditjen e një peme binare. Në qoftë se një pemë binareështë një pemë e kërkimit binar para një rrotullimi atëherë ajo është një pemë e kërkimitbinar pas rrotullimit. Kështu, ne mund ti përdorim të sigurtë rrotullimet për të rirregulluarstrukturën e një peme BST pa u shqetësuar se mund të prishim renditjen e saj.

4

2

31

5

4

2

3

1

5

Rrotullim djathtas mbi 4

3 nga bir idjathte i 2behet bir imajte i 4;

4 behet biri djathte i 2

4

2

31

5

4

2

3

1

5

Rrotullim majtas mbi 2

3 nga bir imajte i 4behet bir idajthte i 2;

2 behet biri majte i 4

5

3 6

2 4

5

4 6

3

2

1 1

4

3 5

2 6

1 4

3

5

2

6

1

Rrotullimmajtas tek

3

Rrotullimdjathtas tek

5

Rrotullimmajtas tek

1

Shtimi ne BST nga rrenja Rregulli i pergjithshem ndjek modelin e treguar

ne prezantim. Neqoftese ne zbritem majtas nga nje nyje x gjate kerkimit per shtim ne kryejme nje rrotullim djathtas mbi x. Neqoftese zbritem djathtas atehere rrotullojme majtas.

Implementimi i algoritmit bazohet ne memorizimin e nyjeve te bredhura gjate kerkimit te nje pike futjeje dhe me tej ne kryerjen e rrotullimeve ne rend te kundert me bredhjen fillestare.

5

3 6

2 4

1Rrotullim

majtas tek 35

4 6

3

2

1

Shtimi ne rrenje ne nje peme te kerkimit binar

Tentojme ta shnderrojme nyjen esaposhtuar 4 ne rrenje te pemes

5

4 6

3

2

1

Shtimi ne rrenje ne nje peme te kerkimit binar

Tentojme ta shnderrojme nyjen esaposhtuar 4 ne rrenje te pemes

4

3 5

2 6

1Rrotullim

djathtas tek 5

Shtimi ne rrenje ne nje peme te kerkimit binar

Tentojme ta shnderrojme nyjen esaposhtuar 4 ne rrenje te pemes

4

3 5

2 6

1 Rrotullimmajtas tek 1

4

3

5

2

6

1

function shtim_BST_rrenja (var t : tabele_peme; elm : tip_elementi) : peme;

{shton elementet ne nje peme te tipit BST - metoda e shtimit nga rrenja}

varugjet : boolean;k : integer;p, q : peme;pa : array [1 . . max_lartesi_BST] of peme;da : array [1 . . max_lartesi_BST] of integer;

beginpa[1] := t.rrenja;p := t.rrenja;da[1] := 1 ;k := 2 ;ugjet := false;

while ((p <> nil) and not(ugjet)) doif p^.element = elm then

ugjet := trueelsebegin

{shqyrto rastin k>max_lartesi_BST}pa[k] := p;if p^.element > elm then

da[k] := 1else

da[k] := 2;p := p^.lidhje[da[k]];k := k + 1;

end;

if not(ugjet) thenbegin

new (p);p^.element := elm;p^.lidhje[1] := nil;p^.lidhje[2] := nil;pa[k-1]^.lidhje[da[k-1]] := p ;{shqyrto rastin pema boshe pra t.rrenja=nil}t.numri := t.numri +1 ;while k > 2 dobegin

q := pa[k-1];q^.lidhje[da[k-1]] := p^.lidhje[3-da[k-1]] ;p^.lidhje[3-da[k-1]] := q ;pa[k-2]^.lidhje[da[k-2]] := p;k:=k-1;

end;t.rrenja := p ;

end; shtim_BST_rrenja := p

end {shtim_BST_rrenja};

function gjej (t : tabele_peme; var p, q : peme ; var d : integer ; elm : tip_elementi) : boolean ;

{gjen vendndodhjen e nyjes se pemes me vlere elm ne pemen t duke ruajtur ne p}{shenjuesin mbi kete nyje peme (ose nil nese ajo nuk ekziston), ne q prindin e p (ose } {nil nese prindi nuk ekziston) dhe ne d kahun e birit (1 nese eshte bir i majte dhe/ose} {2 nese eshte bir i djathte)}var

ugjet : boolean;begin

ugjet := false;p := t.rrenja;q := nil ;while (not(ugjet) and (p <> nil)) doif p^.element = elm then

ugjet := trueelsebegin

if p^.element > elm thend := 1

elsed := 2;

q := p;p := p^.lidhje[d] 

end ;gjej := ugjet 

end {gjej};

Pyetje?