Pemet e Kerkimit Binar (vazhdim)
Leksion 9
Ne kete leksion do te shohim disa veprime te tjera mbi pemet e kerkimit binar.
Rikujtojme nga leksioni i kaluar:
typetip_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;
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};
Peme e kerkimit binar - BST
5
2 9
1 3
4
8
6
7
Heqja e nje nyjeje ne nje peme te kerkimit binar - BST
Heqja e nje nyjeje ne nje peme te kerkimit binar - BST
5
2 9
1 3
4
8
6
7
p
5
2 9
1 3
4
6
7
Rasti 1: p nuk ka bir të djathtë
Heqja e një nyjeje pa bir të djathtë, siç janë 1, 4, 7 ose 8 këtu,është evidente. Zëvëndësojmë shënjuesin që na çon tek p mebirin e majtë të p nëse p ka bir të majtë ose me një shënjuesnil nëse p nuk ka bir të majtë. Me fjalë të tjera, zëvëndësojmënyjen e hequr me birin e vet të majtë. Më sipër tregohetproçesi i heqjes së nyjes 8.
Heqja e nje nyjeje ne nje peme te kerkimit binar - BST
5
2 9
1 3
4
8
6
7
p
r
5
3 9
1 4 8
6
7
r
Rasti 2: biri i djathtë i p nuk ka bir të majtë
Ky rast trajton heqjet e cilësdo nyjeje p që ka një bir të djathtë r që vetë (r) nuk kabir të majtë. Shembuj nyjesh të tilla janë nyjet 2, 3 dhe 6 në pemën e mësipërme.Në këtë rast, ne e lëvizim r në vendin e p duke bashkangjitur nënpemën emëparshme të majtë të p, nëse ka të tillë, si nënpemë të re të majtë të r. P.sh. Përtë hequr nyjen 2 në pemën e mësipërme ne e zëvëndësojmë atë me birin e vet tëdjathtë 3 duke e shndërruar 1 nga birin e majte te 2 në birin e ri të majtë të 3.Proçesi ngjan me skicimin më lart.
Heqja e nje nyjeje ne nje peme te kerkimit binar - BST
5
2 9
1 3
4
8
6
7
p
s
6
2 9
1 3 8
7
s
4
Rasti 3: biri i djathtë i p ka një bir të majtëKy është edhe rasti “i vështirë”, ku r biri i djathtë i p ka një bir të majtë. Le të jetë s pasardhësi ndërrendor ip, d.m.th. s është nyja me vlerën më të vogël më të madhe se p. Atëherë, strategjia jonë është tashkëpusim s nga pozicioni i vet në pemë (gjë e cila në vetvete është gjithmonë e lehtë për tu kryer) dhe tavendosim atë në pozicionin e mëparshëm të p që zhduket nga pema. Në shembullin tonë, për të fshirë nyjen5, ne e lëvizim pasardhësin ndërrendor të 5 nyjen 6 në vendin e 5 siç tregohet më lart.Po ku e dimë ne se nyja s ekziston dhe se mund ta heqim atë lehtësisht? Ne e dimë se ajo ekziston sepsenë të kundërt do të ishim në rastet 1 apo 2 (konsideroni kushtet përkatëse). Ne mund ta shkëpusimlehtësisht nga pozicioni i vet për një arsye shumë të fortë: s është pasardhësi ndërrendor i p dhe si i tillë kavlerën më të vogël në nënpemën e djathtë të p prandaj s nuk mund të ketë bir të majtë (nëse do të kishteatëherë ky bir i majtë do të kishte një vlerë më të vogël se s kështu që ai dhe jo s do të ishte pasardhësindërrendor i p). Meqënëse s nuk ka një bir të majtë ne mund ta zëvëndësojmë atë lehtësisht me birin e vettë djathtë, nëse një i tillë ekziston (operacion identik me rastin 1).
function hiq (var t : tabele_peme; elm : tip_elementi) : boolean;
{heq nyjen e pemes me vlere elm ne pemen t (nese nje nyje } { e tille ekziston) dhe ben rregullimet e duhura ne menyre qe } { pema te gezoje perseri vetite e pemeve te kerkimit binar; }{ kthen true nese veprimi i heqjes perfundon me sukses dhe }{ false ne te kundert }var{p nyja per tu hequr; q prindi i p; r biri i djathte i p; s pasardhesi nderrendor i p}
p, q, r, s : peme ;d : integer ;
begin {hiq}{inicializimi}p := nil;q := nil;r := nil;s := nil;d := 0;
{gjetja e nyjes kandidate per tu hequr, prindit te saj dhe kahut te zbritjes nga prindi} {nepermejt funksionit gjej}
if gjej(t, p, q, d, elm) thenbegin if p^.lidhje[2] = nil then {rasti 1 ku p nuk ka bir te djathte} if q <> nil then
q^.lidhje[d] := p^.lidhje[1] else {nese p nuk ka prind atehere p eshte rrenja e pemes}
t.rrenja := p^.lidhje[1] ; else begin r := p^.lidhje[2] ; if r^.lidhje[1] = nil then {rasti 2 ku biri i djathte i p nuk ka
bir te majte} begin
r^.lidhje[1] := p^.lidhje[1]; if q <> nil then
q^.lidhje[d] := relse {nese p nuk ka prind ateher p eshte rrenja e pemes}
t.rrenja := r ; end
else {rasti 3 ku biri i djathte i p ka bir te majte} begin
{s pasardhesi i p sipas bredhjes nderrendore dhe r prindi i s}s := r^.lidhje[1];while s^.lidhje[1] <> nil
begin r := s; s := r^.lidhje[1]end;r^.lidhje[1] := s^.lidhje[2];s^.lidhje[1] := p^.lidhje[1];s^.lidhje[2] := p^.lidhje[2];if q <> nil then q^.lidhje[d] := selse {nese p nuk ka prind atehere p eshte rrenja e
pemes} t.rrenja := s ;
endend;dispose(p) ;t.numri := t.numri – 1 ;hiq := true
end else
hiq := false;end {hiq};
procedure bredhje_rekursive (var t : tabele_peme);
procedure bredhje_nder_rendore_rekursive (p : peme);{bredhje ne elementet e nenpemes p – metoda nderrendore (in-order) rekursive}
begin { bredhje_nder_rendore_rekursive } if not bosh(p) then begin
bredhje_nder_rendore_rekursive (p^.lidhje[1]) ;writeln (p^.element);bredhje_nder_rendore_rekursive (p^.lidhje[2]) ;
endend { bredhje_nder_rendore_rekursive };
begin {bredhje_rekursive}bredhje_nder_rendore_rekursive(t.rrenja)
end {bredhje_rekursive};
procedure bredhje_iterative (var t : tabele_peme);procedure bredhje_nder_rendore_iterative (p : peme);{bredhje ne elementet e nenpemes p – metoda nderrendore (in-order) iterative}varps : array [1 . . max_lartesi_BST] of peme;n : peme;h : integer;fund : boolean;begin {bredhje_nder_rendore_iterative} n := p; h :=1; fund := false; while not(fund) do begin {while not(fund) do}
while n <> nil dobegin {while n <> nil do}
ps[h] := n;h := h +1;n := n^.lidhje[1]
end {while n <> nil do};
if h = 1 thenfund := true
elsebegin {else}
h := h -1;n := ps[h];writeln (n^.element);n := n^.lidhje [2];
end {else}; end {while not(fund) do};end {bredhje_nder_rendore_iterative};
begin {bredhje_iterative}bredhje_nder_rendore_iterative(t.rrenja)
end {bredhje_iterative};
procedure shkaterro_BST (var t : tabele_peme);{shkaterron pemen t – metoda e rirregullimit te pemes BST duke i rrotulluar nyjet} {derisa te mos kene nenpeme te majte}varp, q : peme;begin {shkaterro_BST}
q := nil;p := t.rrenja;while p<>nil dobegin {while p <>nil do}
if p^.lidhje[1] = nil thenbegin q := p^.lidhje[2]; dispose(p) end elsebegin q := p^.lidhje[1] ; {q bir i majte i p} p^.lidhje[1] := q^.lidhje[2] ; {rrotullo djathtas mbi p} q^.lidhje[2] := p {p asnjehere nuk ka prind}end ;p :=q
end {while p <>nil do}end {shkaterro_BST};
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.
Rrotullimet ne Pemet e Kerkimit Binar
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
function prindi (t : tabele_peme; p : peme) : peme;{kthen prindin e nyjes p ne pemen t ose nil nese ai nuk ekziston (p=rrenja)}var
q, n : peme;ugjet : boolean;
begin {prindi}ugjet := false;if ((t.rrenja <> nil) and (p<>nil)) thenbegin {if ((t.rrenja <> nil) and (p<>nil)) then}
q := nil;n := t.rrenja ;while (not(ugjet) and (n <> nil)) do
if n = p thenugjet := true
elsebegin
if n^.element < p^.element thend := 1
elsed := 2;
q := n ;n := n^.lidhje[d]
end ;end {if ((t.rrenja <> nil) and (p<>nil)) then};if ugjet then
prindi := qelse
prindi := nilend {prindi};
function rrotullo (var t : tabele_peme; x, y : peme; kahu : integer) : boolean;{kryen rrotullim majtas mbi nyjen x te pemes t nese kahu=1 dhe/ose kryen rrotullim} {djathtas mbi nyjen y te pemes t nese kahu=2; kthen true nese veprimi i rrotullimit} {perfundon me sukses dhe false ne te kundert}var{p prindi i x dhe/ose y; d kahu i zbritjes ne peme me reference madhesie p^.element}
p : peme ;d : integer ;
begin {rrotullo}if ((t.rrenja<>nil) and (x<>nil) and (y<>nil)) then
if kahu=1 then {rrotullo majtas mbi x}begin {rrotullo majtas mbi x}
p := prindi(t, x);if p<>nil thenbegin
if p^.lidhje[1]=x thend := 1
elsed:= 2;
p^.lidhje[d] := y ;end else {ndrysho rrenjen e pemes}
t.rrenja := y;x^.lidhje[2] := y^.lidhje[1] ;y^.lidhje[1] := x ;rrotullo := true;
end {rrotullo majtas mbi x}
elseif kahu=2 then {rrotullo djathtas mbi y}begin { rrotullo djathtas mbi y }
p := prindi(t, y);if p<>nil thenbegin
if p^.lidhje[1]=y thend := 1
elsed:= 2;
p^.lidhje[d] := x ;end else {ndrysho rrenjen e pemes}
t.rrenja := x;y^.lidhje[1] := x^.lidhje[2] ;x^.lidhje[2] := y ;rrotullo := true;
end {rrotullo djathtas mbi y};else
rrotullo := false;else
rrotullo := false;end {rrotullo};
Pyetje???
Top Related