pirmas namų darbas. vieno varianto sprendimo pavyzdys.os/files/pirmas_namu_darbas_pvz.pdf ·...
Post on 04-Oct-2019
9 Views
Preview:
TRANSCRIPT
Pirmas namų darbas. Vieno varianto sprendimo pavyzdys.
Sąlygos
Duomenų masyvas: 27; 36; 4; 7; 26; 25; 38; 12; 15; 34
1 užduotis: iš pateikto duomenų masyvo sudarykite visiškai subalansuotą medį;
2 užduotis: iš pateikto duomenų masyvo sudarykite paieškos medį;
3 užduotis: iš pateikto duomenų masyvo sudarykite antros eilės B medį;
4 užduotis: iš pateikto duomenų masyvo sudarykite piramidę;
5 užduotis: iš pateikto duomenų masyvo sudarykite AVL medį. Pašalinkite elementus, įdėtus antru trečiu
ir septintu numeriais;
Infix aritmetinė išraiška 5 · (185 + 19815) - 92840 - 46377 : (14171 - 14162)
6 užduotis: užrašykite aritmetinę išraišką postfix pavidalu
7 užduotis: apskaičiuokite 6 užduotyje gautą išraišką naudojant dėklą
Sprendimai
1 užduotis. Dvejetainis medis, kurio kiekvieno elemento kairiojo ir dešiniojo pomedžių elementų
skaičiai skiriasi ne daugiau kaip vienu, vadinamas visiškai subalansuotu medžiu. Pirmą duomenų
masyvo 27; 36; 4; 7; 26; 25; 38; 12; 15; 34 elementą (t. y. 27) talpinsime į šaknį, likusius skirstome į
dvi dalis: elementai 36; 4; 7; 26 ir 25 bus talpinami į kairįjį pomedį, o 38; 12; 15 ir 34 – į dešinįjį
Su kairiuoju ir dešiniuoju pomedžiais kartojame tuos pačius veiksmus ir gauname:
27
38, 12, 15, 34 36, 4, 7, 26, 25
36
26, 25 4, 7
38
34 12, 15
Padarome tuos pačius veiksmus su trimis duomenų rinkiniais, turinčiais po du elementus. Tuomet
pirmasis elementas taps pomedžio šaknimi, o antrasis bus talpinamas į kairįjį pomedį. Sujungiame
brėžinius į vieną ir gauname:
2 užduotis. Dvejetainis paieškos medis, kurio kiekvienoje viršūnėje esantis elementas yra didesnis už
kairiojo pomedžio elementus ir nedidesnis už dešiniojo pomedžio elementus, vadinamas paieškos
medžiu. Pirmą duomenų masyvo 27; 36; 4; 7; 26; 25; 38; 12; 15; 34 elementą (t. y. 27) talpinsime į
šaknį, o likusius įterpsime po vieną taip, kad medis išliktų paieškos medžiu. Kiekvieno elemento
įterpimas vaizduojamas atskirame brėžinyje. Pastebėkime, kad balansavimo daryti nereikia.
Įterpiame elementą 27 į šaknį
Talpiname elementą 36. Kadangi 36 > 27, tai 36 talpinsime į dešinįjį pomedį
Talpiname 4. Kadangi 4 < 27, tai 4 talpinsime į kairįjį pomedį
27
36 38
4
7
26
25
12
15
34
27
27
36
Tęsiame: įterpiame elementus 7; 26; 25; 38.
27
36 4
27
36 4
7
27
36 4
7
26 27
36 4
7
26
25
27
36 4
7
26
25
38
Įterpiame likusius tris elementus 12; 15 ir 34
3 užduotis. Sudarysime antros eilės B medį naudojant duomenų masyvo 27; 36; 4; 7; 26; 25; 38; 12;
15; 34 elementus.
. B medis
Visos B medžio viršūnės yra dalijamos į dalinius medžius, vadinamus puslapiais:
Kiekvienas puslapis, išskyrus šakninį, turi nuo n iki 2n viršūnių, o skaičius n yra vadinamas medžio
eile. Medžio šaknyje gali būti ir mažiau nei n elementų.
Puslapis yra arba lapas, arba turi (m + 1) vaiką, čia m puslapio elementų skaičius. Visu lapu lygiai yra
vienodi.
27
36 4
7
26
25
38
12
15
34
Kiekviename puslapyje elementai išdėstomi didėjimo tvarka.
Naujo elemento įterpimas
Jeigu puslapio P elementų skaičius m yra mažesnis už 2n, tai x įterpiame tarp P elementų. Kitų B
medžio puslapių modifikuoti nereikia, o medžio aukštis taip pat nepasikeičia.
Jeigu puslapis P jau pilnas, reikia pertvarkyti B medį naudojant vieną iš žemiau pateiktų algoritmų:
1 algoritmas: puslapį P skaidome i du puslapius Q ir R. Visus (2n + 1) elementus dalijame i dvi dalis po n
elementų, o vidurinį elementą perkeliame vienu lygiu aukščiau.
2 algoritmas: stengiamės užpildyti visus jau egzistuojančius lapus ir tik tada kurti naujus. Jeigu, įterpus
naują elementą, lapas yra perpildytas, o greta iš kairės yra ne iki galo užpildytas lapas, tai kritinio lapo
elementus pastumiame į kairę. Pirmiausia į gretimą kairėje lapą nuleidžiame atitinkamą elementą (raktą) iš
aukštesnio lygio ir į atlaisvintą vietą aukštyn perkeliame mažiausią perpildyto lapo elementą, paskui lapo
viduje pastumiame visus elementus.
Analogiškai galima perstumti elementus i dešinę pusę, jei gretimas iš dešinės lapas yra ne iki galo
užpildytas.
Šiuo atveju medis yra antros eilės, taigi n lygus dviem ir puslapyje bus nuo 2 iki 4 viršūnių.
Talpiname elementą 27 į šakninį puslapį, o kitus įterpiame į kairįjį arba dešinįjį puslapius tol, kol vienas
jų neužsipildys. Puslapių elementus rūšiuojame didėjimo tvarka. Įterpiame elementus 36 ir 4:
Įterpiame elementus 7; 26; 25 ir 38
27 27
36
27
36 4
Matome, kad kairysis puslapis jau užsipildė. Sekantis elementas yra 12, ir jį reikėtų talpinti į kairįjį
puslapį (12 < 27), taigi galime taikyti antrą algoritmą. Šakninį elementą 27 talpiname į dešinįjį puslapį, o
nauju šakniniu elementu taps 26.
Tokiu pat būdu talpiname elementą 15
27
36, 38 4, 7, 25, 26
27
36, 38 4, 7, 12, 25, 26
26
27, 36, 38 4, 7, 12, 25
26
27, 36, 38 4, 7, 12, 15, 25
Įterpiame paskutinį elementą, t. y. 34
Dešinysis puslapis tapo perpildytas, antro algoritmo taikyti negalime, nes kairiajame puslapyje irgi nėra
vietos, taigi taikysime pirmą algoritmą. Vidurinį puslapio elementą, t. y. 34, kelsime lygiu aukščiau.
Likusius elementus dalinsime į du puslapius: visi elementai į kairę nuo 34 bus perkelti į naują vidurinį
puslapį, o : visi elementai į dešinę nuo 34 bus perkelti į dešinįjį puslapį.
4 užduotis. Sudarysime piramidę naudojant duomenų masyvo 27; 36; 4; 7; 26; 25; 38; 12; 15; 34
elementus. Piramidė yra pilnas, subalansuotas medis: pirmiausiai užpildoma medžio šaknis, paskui
pirmojo lygmens viršūnės, paskui antrojo lygmens ir t.t. Be to, medis yra sutvarkytas taip, kad
kiekvienos viršūnės vaikai yra nedidesni už pačią viršūnę.
Pritaikome piramidės formavimo algoritmą (jis pateiktas žemiau): pradžioje perkelsime duomenis į
masyvą, po to sutvarkysime elementus. Piramidę bus vaizduojama dviem būdais: medžio ir masyvo
pavidalu.
25
26, 27, 36, 38 4, 7, 12, 15
25
26, 27, 34, 36, 38 4, 7, 12, 15
25, 34
26, 27 4, 7, 12, 15 36, 38
Piramides formavimo algoritmas
MakeHeap ()
begin
(1) for ( i=1; i ≤ N; i++ ) do
(2) ai = ei ;
end do
(3) j = N/2;
(4) for ( i=j; i > 0; i – = 1 ) do
(5) HeapDownOrder ( i, N );
end do
end MakeHeap
Piramides elementu sutvarkymo algoritmas
HeapDownOrder ( p, N )
begin
(1) i=p; j = i+i;
(2) while ( j ≤ N ) do
(3) k = j;
(4) if ( (j+1) ≤ N ) then
(5) if ( aj+1 > aj ) k = j+1;
end if
(6) if ( ai < ak ) then
(7) swap (ai , ak );
(8) i = k; j= i+i;
(9) else
(10) j = N+1;
end if
end do
end HeapDownOrder
Viso turime N=10 elementų: 27; 36; 4; 7; 26; 25; 38; 12; 15; 34. Įkeliame juos į piramidę
27 36 4 7 26 25 38 12 15 34
Dabar j =N/2 =5 ir su i=5, 4, 3, 2 ir 1 vykdysime HeapDownOrder ( i, N ).
1) i=5.
HeapDownOrder ( p, N )
begin
(1) i=p; j = i+i;
(2) while ( j ≤ N ) do
i=5; j=10;
while ( 10 ≤ 10 ) do t.y. vieną kartą
10 9 8
7 6 5
4
3 2
1
27
36 4
7
12
26
15
25
34
38
(3) k = j;
(4) if ( (j+1) ≤ N ) then
(5) if ( aj+1 > aj ) k = j+1;
end if
(6) if ( ai < ak ) then
(7) swap (ai , ak );
(8) i = k; j= i+i;
(9) else
(10) j = N+1;
end if
end do
end HeapDownOrder
k=10;
if ( (11) ≤ 10 ) then netenkinama sąlyga
nevykdome
if ( a5 < a10 ) then šiuo atveju 26 < 34
keičiame 26 ir 34 vietomis
i=10; j=20
Po šio žingsnio turime:
27 36 4 7 34 25 38 12 15 26
2) i=4.
HeapDownOrder ( p, N )
begin
(1) i=p; j = i+i;
(2) while ( j ≤ N ) do
(3) k = j;
(4) if ( (j+1) ≤ N ) then
(5) if ( aj+1 > aj ) k = j+1;
end if
(6) if ( ai < ak ) then
(7) swap (ai , ak );
(8) i = k; j= i+i;
(9) else
i=4; j=8;
while ( j ≤ 10 ) do dabar j=8, t. y vykdome
k=8;
if ( (9 ≤ 10 ) then tenkinama sąlyga
if ( a9 > a8 ) šiuo atveju 15 > 12 =true, k=9
end if
if ( a4 < a9 ) then šiuo atveju 7 < 15
keičiame 7 ir 15 vietomis
i=8; j=16 ir einame į (2)
while ( j ≤ 10 ) do dabar j=16, t. y nevykdome
10 9 8
7 6 5 4
3 2
1
27
36 4
7
12
34
15
25
26
38
(10) j = N+1;
end if
end do
end HeapDownOrder
Po šio žingsnio turime:
27 36 4 15 34 25 38 12 7 26
3) i=3. Einame į viršūnę numeriu 3, ir sukeičiame vietomis su jos didžiausiu vaiku. Šiuo atveju
keisime vietomis elementus 4 ir 38
Po šio žingsnio turime:
10 9 8
7 6 5 4
3 2
1
27
36 4
15
12
34
7
25
26
38
10 9 8
7 6 5
4
3 2
1
27
36 38
15
12
34
7
25
26
4
27 36 38 15 34 25 4 12 7 26
4) i=2. Einame į viršūnę numeriu 2, šios viršūnės (reikšmė 36) vaikai yra nedidesni (12 ir 34), taigi
nieko nekeičiame.
5) i=1. Einame į viršūnę numeriu 1, šios viršūnės (reikšmė 27) abu vaikai yra didesni (36 ir 38),
taiga sukeičiame pirmą viršūnę .su jos didesniu vaiku, t.y. 38.
Po šio žingsnio turime:
38 36 27 15 34 25 4 12 7 26
5 užduotis. Iš dalies subalansuotas paieškos medis, kurio bet kurios viršūnės kairiojo ir dešiniojo
pomedžių aukščiai skiriasi nedaugiau nei vienetu, vadinamas AVL medžiu. Pirmą duomenų masyvo 27;
36; 4; 7; 26; 25; 38; 12; 15; 34 elementus įkelsime į AVL medį, atliksime (jei reikės) balansavimą, o
paskui pašalinsime elementus, įdėtus antru trečiu ir septintu numeriais, t. y. 36, 27 ir 4.
Įterpiame pirmas keturias viršūnes (27, 36, 4, 7) taip pat, kaip į paieškos medį. Medis lieka iš dalies
subalansuotas
10 9 8
7 6 5
4
3 2
1
38
7
36 27
15
12
34
7
25
26
4
27
36 4
27
36 4
7
27
27
36
Įterpiame viršūnę 26. Dabar viršūnės 27 kairiojo pomedžio aukštis yra dviem didesnis, negu
dešiniojo. Atliksime viengubą pasukimą į kairę (jo schema pateikta puslapio apačioje). Šiuo atveju A
yra elementas 4, B yra elementas 7, pomedžiai L, P ir R tušti, o N yra elementas 26
Viengubo pasukimo į kairę schema. Toks pasukimas atliekamas, kai įterpiame viršūnę į kraštinį
pomedį.
Medis tapo iš dalies subalansuotu, taigi įterpiame viršūnę 25. Po šio žingsnio vėl reikės balansuoti
medį (tam naudosime dvigubo pasukimo schemą, pateiktą žemiau)
Pirmu žingsniu pasuksime į kairę (šiuo atveju C yra viršūnė 7), o tada į dešinę (B yra viršūnė 26)
27
36 4
7
26
27
36 7
26 4
Dvigubo pasukimo schema. Toks pasukimas atliekamas, kai įterpiame viršūnę į vidinį pomedį.
27
36 7
26 4
25
27
36 26
25
7
4
27
36
26
25
7
4
Įterpiame viršūnę 38. Po šio žingsnio vėl reikia atlikti balansavimą (viengubas posūkis į kairę)
Įterpiame viršūnes 12 (po šio žingsnio balansavimo atlikti nereikia) ir 15 (dvigubas pasukimas):
27
36
26
25
7
4
38
36
38
26
25
7
4 27
36
38
26
25
7
4 27
12
15
36
38
26
15
7
4 27
12 25
Paskutinė viršūnė 34. Po šio žingsnio balansavimo atlikti nereikia.
Pašalinkime kelias viršūnes: pirmą šalinsime viršūnę 36. Ji turi abu vaikus, taigi ją keisime kairiojo
pomedžio labiausiai į dešinę pusę nutolusia viršūne (34, šiuo atveju nereikės balansavimo) arba dešiniojo
pomedžio labiausiai į kairę pusę nutolusia viršūne (38, šiuo atveju reikėtų balansuoti -patikrinkite).
Viršūnė 27 yra lapas, ją tiesiog pašaliname ir įsitikiname, kad balansavimo atlikti nereikia
36
38
26
15
7
4 27
12 25
34
34
38
26
15
7
4 27
12 25
34
38
26
15
7
4
12 25
Šaliname viršūnę 4. Ji irgi yra lapas; pastebėkime, kad šiuo atveju reikia atlikti balansavimą (naudojamas
viengubas pasukimas)
6 užduotis: užrašykite aritmetinę išraišką 5 · (185 + 19815) - 92840 - 46377 : (14171 - 14162) postfix
pavidalu. Pritaikome žemiau pateiktą Infix2Postfix algoritmą
Infix išraiškos užrašymas postfix forma.
/* S - deklas */
Infix2Postfix()
begin
(1) Infix išraiška papildome pradžios ” [ ” ir pabaigos ”
] ” simboliais.
(2) while (FileNonEmpty) do
(3) `s = readDataFile();
(4) select case (s):
(5) case ( "[", "(" )
(6) S.Push(s);
(7) case ( s yra operandas )
(8) print(s);
(9) case ( ^, *, /, +, − )
(10) h = S.ReadTop();
(11) select case (h):
(12) case ( "[", "(", h < s )
(13) S.Push(s);
(14) case ( s <= h )
(15) h = S.Pop();
(16) print(h);
(17) goto 10;
end select case
(18) case ( ")" )
(19) h = S.Pop();
(20) while ( h != "(" ) do
(21) print(h);
(22) h = S.Pop();
end do
(23) case ( "]" )
(24) h = S.Pop();
(25) while ( h != "[" ) do
(26) print(h);
(27) h = S.Pop();
end do
end select case
end do
end Infix2Postfix
Visus atliekamus veiksmus patogu rašyti į lentelę.
34
38
26
15
7
12 25
34
38
26
25
15
7
12
5 * (185 + 19815) - 92840 - 46377 : (14171 - 14162)
Papildome skliaustais: [ 5 * (185 + 19815) - 92840 - 46377 : (14171 - 14162) ]
Įėjimas Dėklas Postfix
[ [
5 [ 5
* [ *
( [ * (
185 [ * ( 185
+ [ * ( +
19815 [ * ( + 19815
) [ * +
- [ - *
92840 [ - 92840
- [ - -
46377 [ - 46377
: [ - :
( [ - : (
14171 [ - : ( 14171
- [ - : ( -
14162 [ - : ( - 14162
) [ - : -
] [ - :
[ -
Gavome: 5 185 19815 + * 92840 - 46377 14171 14162 - : -
7 užduotis: apskaičiuosime gautą išraišką 5 185 19815 + * 92840 - 46377 14171 14162 - : -
Postfix išraiškos reikšmės skaičiavimas. PostfixValue (S) /* S – dėklas */ begin (1) while (FileNonEmpty) do (2) s = readDataFile(); (3) if (s yra skaičius) then (4) S.Push(s);
else (5) b = S.Pop(); (6) a = S.Pop(); (7) c = a op(s) b; (8) S.Push(c);
end if end do end PostfixValue
Įėjimas Dėklas Reikšmė
5 5
185 5 185
19815 5 185 19815
+ 5 20000 185+19815=20000
* 100000 5*20000 = 100000
92840 100000 92840
- 7160 100000-92840=7160
46377 7160 46377
14171 7160 46377 14171
14162 7160 46377 14171 14162
- 7160 46377 9 14171-14162=9
: 7160 5153 46377:9=5153
- 2007 7160-5153=2007
top related