Professional Documents
Culture Documents
Kapitulli IV - Rekursioni
Kapitulli IV - Rekursioni
Kapitulli 4 Rekursioni
Në këtë kapitull studiojmë rekursionin1 . Në shkencën e informatikës, rekursioni është një qasje
për të zgjidhur një problem informatik ku zgjidhja varet nga zgjidhjet e rasteve më të vogla të
të njëjtit problem. Rekursioni i zgjidh probleme të tilla duke përdorur funksione që thërrasin
vetveten që nga vetë kodi i tyre.
Ne fillojmë duke studiuar një rast klasik rekursiv, llogaritja e numrit faktorial, shkurtimisht
faktorialin. Pasi të shpjegojmë se si funksionon rekursioni, ne zhvillojmë disa parime për
zhvillimin e algoritmeve rekursive dhe më pas disa shembuj.
1 𝑖𝑓 𝑛 = 0
𝐹𝑎𝑘𝑡𝑜𝑟𝑖𝑎𝑙(𝑛) = {𝑛 ∙ 𝐹𝑎𝑘𝑡𝑜𝑟𝑖𝑎𝑙(𝑛 − 1))
𝑖𝑓 𝑛 > 0
Zbërthimi i Faktorial (3) duke përdorur formulën rekursive të Figurës 4.1 është paraqitur në
Figurën 4.2. Nëse e studioni me kujdes Figurën 3.2, do të vini re se zgjidhja rekursive për një
problem përfshin një “udhëtim” të dyanshëm: fillimisht ne e zbërthejmë problemin nga lart
poshtë, pastaj e zgjidhim atë nga poshtë lart.
Faktorial(0) = 1
Duke gjykuar nga ky shembull, llogaritja rekursive duket të jetë shumë më e gjatë dhe më e
vështirë se ajo iterative. Pra, pse do të dëshironim të përdorim metodën rekursive? Megjithëse
llogaritja rekursive duket më e vështirë kur përdorim laps-e-letër, shpesh është një zgjidhje
shumë më e lehtë dhe më elegante kur përdorim kompjuter. Gjithashtu, ai ofron një thjeshtësi
konceptuale për krijuesin dhe lexuesin.
1 Vjen nga fjala latinisht recursiō (“the act of running back or again, return”)
Nëse krahasoni versionin iterativ dhe versionin rekursiv të faktorialit, duhet të habiteni
menjëherë se sa i thjeshtë është kodi në versionin rekursiv. Së pari, nuk ka asnjë cikël. Versioni
rekursiv përbëhet nga një deklaratë e thjeshtë përzgjedhjeje që kthen ose vlerën 1 ose produktin
e dy vlerave, njëra prej të cilave është një thirrje në vetë faktorialin.
Tani që kemi parë se si funksionon rekursioni, le ta kthejmë vëmendjen tonë tek hapat për
hartimin e një algoritmi rekursiv. Fillimisht shikojmë metodologjinë bazë të projektimit, më
pas diskutojmë kufizimet e rekursionit dhe në fund hartojmë dhe implementojmë një algoritëm
tjetër rekursiv.
faktorial (n - 1), hapi 2.1 ofron një pjesë të zgjidhjes së problemit të përgjithshëm duke i kthyer
një vlerë algoritmit thirrës.
Figura 4.3 Gjurmimi i algoritmit rekursiv
Program faktorial
1. faktN = faktR (3)
2. Output(faktN)
3
EndProgram 6
Siç e shohim në hapin 2.1, pjesa e përgjithshme e zgjidhjes është thirrja rekursive: hapi 2.1
thërret veten për të zgjidhur problemin. Këtë e shohim edhe në Figurën 4.2. Në çdo thirrje
rekursive, madhësia e problemit zvogëlohet, nga faktoriali i 3-it, në faktorialin e 2-it, në 1, dhe
në fund në faktorialin 0-s.
Hapi që "zgjidh" problemin njihet si rasti bazë. Çdo algoritëm rekursiv duhet të ketë të paktën
një rast bazë. Pjesa tjetër e algoritmit njihet si rasti i përgjithshëm. Në shembullin tonë faktorial,
rasti bazë është faktorial (0); rasti i përgjithshëm është n × faktorial (n - 1). Rasti i përgjithshëm
përmban logjikën e nevojshme për të zvogëluar madhësinë e problemit.
Çdo thirrje rekursive ose duhet të zgjidhë një pjesë të problemit ose të zvogëlojë përmasën e
problemit.
Në problemin faktorial, pasi të jetë arritur rasti bazë, fillon zgjidhja. Tani e dimë një pjesë të
përgjigjes dhe mund ta kthejmë atë pjesë në instruksionin tjetër, më të përgjithshëm. Kështu,
në Algoritmin 4.1, ne e dimë këtë faktorial (0), ai është 1, dhe ne e kthejmë atë vlerë. Kjo na
lejon të zgjidhim rastin tjetër të përgjithshëm
Tani mund ta kthejmë vlerën e faktorialit (1) në rastin më të përgjithshëm, faktorial (2), për të
cilin dimë se është
Ndërsa zgjidhim çdo rast të përgjithshëm me radhë, ne jemi në gjendje të zgjidhim rastin tjetër -
më të përgjithshëm derisa të zgjidhim përfundimisht rastin më të përgjithshmin, problemin
origjinal.
Duke iu rikthyer qëllimit të këtij seksioni, tani jemi gati të deklarojmë rregullat për hartimin e
një algoritmi rekursiv:
Në kombinimin e rastit bazë dhe rastit të përgjithshëm në një algoritëm, duhet t'i kushtojmë
vëmendje logjikës. Çdo thirrje duhet të zvogëlojë madhësinë e problemit dhe ta zhvendosë atë
drejt rastit bazë. Rasti bazë, kur arrihet, duhet të përfundojë pa thirrje në algoritmin rekursiv;
dmth duhet të ekzekutojë një kthim.
Kufizimet e rekursionit
Ne kemi dhënë vetëm një shpjegim të shkurtër të rekursionit në këtë seksion. Rekursioni
funksionon më mirë kur algoritmi përdor një strukturë të dhënash që mbështet natyrshëm
rekursionin. Një strukturë e tillë e të dhënave është pema (tree). Pemët janë një strukturë
natyrale rekursive dhe rekursioni funksionon mirë me to.
Zgjidhjet rekursive mund të sjellin shpenzime të mëdha (si në kohë ashtu edhe në kujtesë),
sepse ato përdorin thirrjet e funksionit që përbën algoritmin. Çdo thirrje kërkon kohë për t'u
ekzekutuar. Prandaj, një algoritëm rekursiv në përgjithësi funksionon më ngadalë se sa zbatimi
i tij jorekursiv2 .
Ju nuk duhet të përdorni rekursion nëse përgjigja për ndonjë nga pyetjet e mëposhtme është jo:
2 1. Shumica e kompiluesve të sotëm optimizojne kodin kur është e mundur. Kur rekursioni ndodh në fund të një
funksioni (i njohur si tail recursion), një kompilues i optimizuar e kthen kodin rekursiv në një cikël të thjeshtë,
duke eliminuar kështu joefikasitetin e thirrjes së funksionit rekursiv.
Sa herë që bëjmë një thirrje, ne përdorim një pjesë të kujtesës të kompjuterit. Nëse rekursioni
është i thellë, domethënë nëse ka shumë thirrje rekursive, mund të zihet e gjithë kujtesa e
mundshme për aplikimet.
Për shkak të kohës dhe kujtesës së tepërt, algoritmet si faktoriali zhvillohen më mirë në mënyrë
iterative nëse përfshihen numra të mëdhenj. Si rregull i përgjithshëm, algoritmet rekursivë
duhet të përdoren vetëm kur efektshmëria e tyre është logaritmike.
Gjatë hartimit të algoritmeve rekursive duhet të keni parasysh tre pikat e mëposhtme:
Shtrimi i problemës. Le të jetë dhënë vargu i n numrave të parë natyrorë 1, 2, 3, ⋅⋅⋅ , n. Kërkohet
që të llogaritet shuma e tyre në funksion të numrit të kufizave të vargut, n,
S(n) = 1 + 2 + ⋅⋅⋅ + n
Në këtë mënyrë gjetëm një formulë rekurrente për llogaritjen e shumës së n numrave natyrorë
të parë.
Për të përcaktuar rastin bazë kemi disa mundësi. Mund të konsiderojmë si rast bazë situatën
kur n = 0 dhe në këtë rast shuma e kufizave është e barabartë me 0 (nuk ka asnjë kufizë për të
mbledhur) ose situatën kur n = 1 dhe shuma e kufizave është e barabartë me 1 (vetëm vlera 1
për t'u mbledhur). Shohim se çdo thirrje rekursive zvogëlon përmasën e problemit me 1 dhe
rasti bazë do të arrihet mbasi n është pozitive.
Shtrimi i problemës. Të hartohet një algoritëm rekursiv që kontrollon nëse një vlerë e caktuar
e plotë ndodhet në një array me n elemente që janë numra natyrorë.
Algoritmi 4.3 Algoritmi rekursiv për verifikimin ekzistencës së një vlere në një array
Func tion e shte Vle r a (n: Inte ge r , a: Inte ge r , v: Inte ge r ) Re tur n Boole an
1. If (n = 1) Then
1.1 If a[1] = v
1.1.1 Return True
1.2 Else
1.2.1 Return False
2. If a[n] = v Then
2.1 Return True
2.2 Else
2.2.1 Return (a[n–1] = v)
EndFunction
Shtrimi i problemës. Vargu i numrave të Fibonaçit është krijuar nga matematikani italian
Leonardi i Pizës (i ashtuquajturi Fibonacci) në shekullin e trembëdhjetë për të modeluar rritjen
e popullatës së minjve. Për të llogaritur numrin e minjve të lindur në muajin e n-të ai përcaktoi
formulën rekurrente,
F(n) = F(n − 1) + F(n − 2), (4.1)
me vlerat e mëposhtme në rastin bazë: F0 = 0 dhe F1 = 1. Llogaritja e disa vlerave jep vargun e
mëposhtëm,
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,…
Formula e Fibonaçit nuk rezultoi një vlerësues i mirë për parashikimin e numrit të brejtësve
por ajo u mirëprit në aplikime të tjera mbasi ka cilësi interesante. Ekzistojnë aplikime
interesante të numrave të Fibonaçit edhe në vetë informatikë. Janë zbuluar edhe vargje të tjerë
numerikë të ngjashëm me vargun Fibonaçi që përdoren në parashikimin e çmimeve të mallrave
dhe të stoqeve.
Algoritmi fibonaciR, është një algoritëm rekursiv për llogaritjen e kufizës të n-të të vargut të
Fibonaçit.
Algoritmi për llogaritjen e numrave të Fibonaçit, realizuar në trajtën e një funksioni rekursiv,
përbëhet nga dy thirrje zvogëluese.
Megjithëse relacioni rekurrencial i llogaritjes së numrave të Fibonaçit është i lehtë për t’u
programuar në trajtë rekursive, ky algoritëm nuk është aspak i efektshëm mbasi çdo hap
rekursiv prodhon dy thirrje të funksionit Fibonaçi, të cilat kërkojnë llogaritjen e vlerave tashmë
të llogaritura. Thirrjet e ekuacionit rekurrencial të Fibonaçit (4.1), mund të paraqiten në trajtë
grafike, në formën e një pemë por me rrënjë lart të quajtur pema e rekursionit (recursion tree).
Nyjet e pemës përmbajnë thirrjet ndërsa shigjetat tregojnë thirrjet pasuese. Dinamika e thirrjeve
përfundon gjithmonë në rastet bazë.
Në Figurën 4.4 paraqitet pema e thirrjeve për llogaritjen e kufizës të pestë të vargut me anë të
thirrjes fibR(5) . Nga pema e thirrjeve për llogaritjen e kufizës të pestë të vargut të Fibonaçit,
fibR(5) , shihet se fibR(2) llogaritet 3 herë, fibR(3) llogaritet 3 herë, etj. Kjo tregon se kemi një
përsëritje të llogaritjeve të njëjta, gjë që është një shpenzim i tepërt i kohës. Ky problem nuk
shfaqet në zbatimet iterative të llogaritjes së numrave të Fibonaçit.
Gjithashtu, në pemën e rekursionit, janë vendosur edhe vlerat që kthen çdo thirrje rekursive.
Në përfundim të ekzekutimit, thirrja fibR (5) kthen vlerën 5.
Figura 4.4 Pema e rekursionit për llogaritjen e kufizave të vargut Fibonaçi për n = 5
fibR (5)
=5
fibR (2) fibR (1) fibR (1) fibR (0) fibR (1) fibR (0)
=1 =1 =1 =0 =1 =0
Ndërsa në Figurën 4.5, numrat e vendosur mbi shigjetat tregojnë rradhën e ekzekutimit të çdo
thirrjeje rekursive, për llogaritjen e kufizave të vargut Fibonaçi për n = 5.
fibR (5)
1 10
fibR (2) fibR (1) fibR (1) fibR (0) fibR (1) fibR (0)
4 5
Shtrimi i problemës. Të hartohet një algoritëm rekursiv i tipit procedurë që afishon vargun e
numrave natyrorë duke filluar nga një numër i dhënë n deri tek numri 1. Për shembull kur n =
Duke patur në konsideratë se si funksionon algoritmi rekursiv, këtu do të bëjmë një marifet,
instruksioni i afishimit do të vendoset para thirrjes rekursive të algoritmit.
Në Figurën 4.# paraqitet një gjurmim i algoritmit afishimMbrapsht(), krijuar nga një ekzekutim
i procedurës me vlerë fillestare n = 3. Rezultati që prodhon algoritmi është vargu i numrave 3,
2, 1, ku çdo numër afishohet në fillim të rreshtit.
afishimMbrapsht(3)
If 3 > 0 Then
Output(3)
afishimMbrapsht (2)
Else Return
If 2 > 0 Then
Output(2)
afishimMbrapsht (1)
Else Return
If 1 > 0 Then
Output (1)
afishimMbrapsht (0)
Else Return
If 0 > 0 Then
Output (0)
afishimMbrapsht (0)
Else Return
B. Vika & Dh. Tole
1 Strukturë të Dhënash | 54
Algoritmet rekursive janë shumë të përpshtatshme për disa probleme të caktuara, por është e
rëndësishme të theksojmë se ata, në përgjithësi, kërkojnë më shumë kohë ekzekutimi dhe
hapsirë kujtese sesa algoritmet iterativë. Kur analizohet një algoritëm rekursiv për
kompleksitetin e tij, duke numëruar veprimin dominues, përftohet një formulë rekursive. Këto
formula rekursive quhen lidhje rekurrenciale, shkurtimisht rekurrenca. Rekurrencat nuk
paraqiten me anë të ndonjë një formule të shtjellur. Si rrjedhojë është e domosdoshme zgjidhja
e rekurrencave për të fituar një formulë të shtjellur.
• Metoda e iteracionit
• Metoda e pemëve të rekursionit
• Metoda Master
• Metoda e ekuacioneve karakteristike
Sh(0) = 0 për n = 0
Supozoni se keni një varg numerik që kënaq një lidhje të caktuar rekurrenciale dhe me kushtet
fillestare. Shpesh është e dobishme të dini një formulë të qartë për vargun numerik, veçanërisht
nëse keni nevojë të llogaritni kufizat me indekse shumë të mëdhenj ose nëse keni nevojë të
shqyrtoni vetitë e përgjithshme të vargut. Një formulë e tillë eksplicite quhet zgjidhje e
ekuacionit rekurrencial.
Metoda e iteracionit
Metoda më themelore për gjetjen e një formule eksplicite për një varg numerik të përcaktuar
në mënyrë rekursive është metoda e iteracionit (metoda e zëvendësimeve te njëpasnjëshme).
Metoda e Iteracionit funksionon si vijon: duke pasur parasysh një sekuencë a1 , a2 , a3 , … të
përcaktuar nga një lidhje rekurrenciale dhe kushtet fillestare, ju niseni nga kushtet fillestare
dhe llogaritni kufizat e njëpasnjëshëm të vargut derisa të shihni një motiv (pattern) që shfaqet
duke llogaritur kufizat e vargut. Në atë pikë, ju hamendësoni një formulë eksplicite (të
shtjellur).
Le të llogaritim disa vlera nga rekurrenca për të parë mundësinë e gjetjes së ndonjë motivi,
Sh(1) = Sh(0) + 1 = 0 + 1 = 1
Sh(2) = Sh(1) + 1 = 1 + 1 = 2
Sh(3) = Sh(2) + 1 = 1 + 1 + 1= 3
⋯
Sh(n) = Sh(n-1) + 1 = 1 + 1 + 1 + ⋯ +1 = n
Si rrjedhim Algoritmi 4.1 për llogaritjen e faktorialit me anë të rekursionit bën pjesë në klasën
e kompleksitetit O(n).
Metoda e zëvendësimit mund të shihet edhe nën një këndvështrim tjetër, atë të pemës së
rekursionit. Një pemë rekursioni për një rekurrence është një paraqitje pamore (vizuale) dhe
T(n) = 2T(n/2) + n,
Duke lënë mënjanë për momentin rastin bazë, këtë rekurrencë ne mund ta interpretojmë në
trajtën:
1 n/2
Tani mund të shihet se si rekurrenca është reflektuar në nivelet 0 dhe 1 të pemës së rekursionit.
Kulmi i sipërm i pemës paraqet T(n), në nivelin pasues kemi dy nënprobleme të madhësisë n/2,
që na japin termin rekursiv 2T(n/2) të rekurrencës. Pastaj pasi zgjidhim këto dy probleme
kthehemi në nivelin 0 të pemës dhe kryejmë një punë shtesë prej n njësish për termin jorekursiv
të rekurrencës.
Tani mund të vazhdojmë vizatimin e mëtejshëm të pemës. Plotësimi i asaj që ka mbetur nga
niveli 1 dhe shtimi i disa niveleve të tjera paraqitet në Figurën 4.7.
1 n/2 n / 2 + n / 2= n
2 n/4 n/4+n/4+n/4+n/4=n
3 n/8 8 (n / 8) = n
Le të përmbledhin atë ç’ka na thotë diagrama. Në nivelin zero (në krye), janë kryer n njësi punë
shtesë. Shohim që në secilin nivel pasues, kemi përgjysmuar madhësinë e problemit dhe
dyfishuar numrin e nënproblemeve. Gjithashtu shohim që në nivelin 1, secili nga dy
nënproblemet kërkon n/2 njësi kosto shtesë, dhe se gjithsej janë kryer n njësi punë shtesë në
këtë nivel. Në mënyrë të ngjashme niveli 2 ka 4 nënprobleme të përmasës n/4 secili dhe prandaj
kryhet 4(n/4) = n punë shtesë.
Shohim që për këtë problem, në nivelin i, kemi 2i nënprobleme të përmasës n/2i. Më tej,
përderisa një problem i madhësisë 2i kërkon 2i njësi punë shtesë, do të kemi (2i) [n/(2i)] = n
njësi pune shtesë për nivel.
Për të llogaritur numrin e niveleve të pemës së rekursionit, mjafton të vëmë në dukje që në çdo
nivel madhësia e problemit përgjysmohet dhe pema mbyllet kur madhësia e problemit bëhet 1.
Prandaj pema përbëhet nga (log n) + 1 nivele. E gjithë pema është paraqitur në Figurën 4.8.
1 n/2 n / 2 + n / 2= n
2 n/4 n/4+n/4+n/4+n/4=n
3 n/8 8 (n / 8) = n
. . . . . . . . . . . . . . . . . . . . . . .
lg n 1 . . . n.1
Niveli më i poshtëm është i ndryshëm nga nivelet e tjerë, në të cilët puna përshkruhej nga pjesa
rekursive e rekurrencës (në rastin në shqyrtim nga T(n) = 2T(n/2) + n). Në nivelin më të
poshtëm, puna përcaktohet nga rasti bazë. Kështu ne duhet të llogaritim numrin e problemeve
të madhësisë 1 (duke supozuar se kemi vetëm një rast bazë) dhe ta shumëzojmë pastaj këtë
vlerë me T(1). Në këtë nivel ne kemi n nënprobleme dhe puna shtesë e kryer në nivelin bazë,
me supozimin që T(1) = 1, është n.
Sapo të njohim me saktësi se sa nivele janë dhe se sa punë kryhet në çdo nivel atëherë mund të
shumojmë punën e kryer në të gjithë nivelet duke përftuar në këtë mënyrë zgjidhjen e
rekurrencës.
Në rastin në shqyrtim, kemi (log n) + 1 nivele, dhe në çdo nivel puna e kryer është n njësi. Pra
arrijmë në përfundimin se e gjithë puna që duhet për të zgjidhur problemin e përshkruar, me
kusht fillestar T(1) = 1, është T(n) = n((log n) + 1). Puna gjithsej e kryer nëpërmjet pemës është
zgjidhja e rekurrencës në shqyrtim mbasi pema thjesht modelon procesin e përsëritjes të
rekurrencës.
𝑛
𝑇 (𝑛) = 𝑎 ∙ 𝑇 ( ) + 𝑓(𝑛)
𝑏
ku,
f(n), është një funksion asimptotikisht pozitiv që paraqet numrin e veprimeve per ndarjen /
bashkimin e nenproblemeve,
a ≥ 1, paraqet numrin e nënproblemeve (numër i plotë).
b > 1, paraqet madhësinë e një nënproblemi (numër i plotë).
Për qëllimet e lëndës ne do të trajtojmë zgjidhjet e një versioni të thjeshtuar të teoremës Master
për të zgjidhur rekurrenca të formës:
𝑛
𝑇 (𝑛) = 𝑎 ∙ 𝑇 ( ) + 𝑛𝑑
𝑏
Shënim
Teorema Master nuk paraqet zgjidhjen një ekuacionin rekurrencial në trajtën e një formule por
përcakton klasën e kompleksitetit.
Metoda e Iteracionit mund të jetë ndërlikuar, por kur lidhja rekurrenciale i referohet vetëm një
termi të mëparshëm (dhe ndoshta ndonjë funksioni të n) ai mund të funksionojë mirë.
Megjithatë, përpjekja për të t’u zbatuar ndaj një lidhjeje rekurrenciale si për shembull F(n) =
F(n-1) + F(n-2) do të jetë shumë e ndërlikuar. Do të na duhet të mbajmë gjurmët e dy grupeve
të termave të mëparshëm, secili prej të cilëve shprehet me dy terma të mëparshëm, e kështu me
radhë. Gjatësia e formulës do të rritej në mënyrë eksponenciale (dyfish çdo herë, në fakt). Për
fat të mirë ka një metodë për zgjidhjen e lidhjeve rekurrenciale që funksionon shumë mirë në
lidhje si kjo.
Ndërkaq, vëmë në dukje se ekziston një formulë e drejpërdrejtë për llogaritjen e numrave të
Fibonaçit duke përdorur mjetet që ofron matematika për zgjidhjen e rekurrencave lineare
homogjene të rendit të dytë me koeficientë konstantë të formës
ku a, b dhe c janë numra reale (a ≠ 0) të quajtur koeficientë të rekurrencës dhe S(n) është termi
i përgjithshëm i një vargu të pafundëm që duhet të gjendet. Duke zbatuar këtë teoremë për
vargun Fibonaçi (a = 1, b = –1, c = –1), me konditat fillestare të dhëna, përftohet formula për
llogaritjen drejtpërsëdrejti të numrave të Fibonaçit
𝟏
̂𝐧 ),
𝐅(𝐧) = √𝟓 (∅𝐧 − ∅ (4.4)
𝟏
ku ∅ = (𝟏 + √𝟓)/𝟐 ≈ 𝟏. 𝟔𝟏𝟖𝟎𝟑 dhe ̂
∅ = − ≈ −𝟎. 𝟔𝟏𝟖𝟎𝟑. 3
∅
Është e vështirë të besohet që kjo formulë, që përmban një fuqi të plotë të çfardoshme të një
numri irracional, të prodhojë të gjithë elementet e vargut Fibonaçi, por ja që ndodh.
Një nga të përfitimet e formulës (4.4) është se ajo tregon që numrat e Fibonaçit F(n) rriten në
mënyrë eksponenciale domethënë, F(n) ∈ O(∅𝒏 ). Kjo rrjedh nga fakti që termi i dytë i formulës
(5.7) shkon në zero kur n bëhet pambarimisht e madhe. Në të vërtetë, mund të provohet që
ndikimi i termit të dytë në vlerën e F(n) mund të përftohet nga rrumbullakimi i vlerës të termit
të parë tek numri i plotë më i afërt. Me fjalë të tjera, për çdo numër të plotë jonegativ
𝟏
𝐅(𝐧) = ( ∅𝐧 ), e rrumbullakosur tek numri i plotë më i afërt.
√𝟓
Ne Algoritmin rekursiv 4.4 (seksioni 4.3.3) për llogaritjen e numrave te Fibonaçit si veprim
dominues do të konsiderojme mbledhjen në rreshtin 3. Duke qenë se numri i thirrjeve varet
vetem nga numri n, atëherë funksionin që do të shërbejë për të llogaritur kompleksitetin kohor
të algoritmit në fjalë do ta shprehim si një funksion të n, M(n). Numrat e veprimeve të
mbledhjes të nevojshme për llogaritjen e F(n – 1) dhe F(n – 2) janë respektivisht M(n – 1) dhe
M(n – 2), plus një mbledhje tjetër për të llogaritur shumën e tyre. Kështu që përftojmë
rekurrencën që pason për numrin e përgjithshëm të mbledhjeve,
3 Konstantja ∅ njihet me emrin Prerja e artë (Gold section). Në antikitet ka qenë konsideruar si raporti më i
pëlqyeshëm për brinjët e një drejtkëndëshi dhe është përdour shumë nga skulptorët dhe arkitektët.
Klasa shumë e keqe e kompleksitetit kohor e algoritmit është e përcaktuar nga formula
llogaritëse (5.8). Me të vërtetë, algoritmi përbëhet nga dy thirrje rekursive me përmasa më të
vogla dhe që përsëriten.
4.5 Përmbledhje
4.6 Ushtrime
1. Nëse njihet kufiza n-të e një vargu aritmetik dhe diferenca e përbashkët ndërmjet dy
kufizave të njëpasnjëshëm, d, atëherë kufiza e (n + 1)-të gjendet nga formula rekurrente
an+1 = an + d. Të gjendet kufiza e 9-të e vargut kur njihet d = 7 dhe kufiza e 8-të është 51.
2. Nëse njihet kufiza e n-të e një vargu gjeometrik dhe herësi i përbashkët, q, atëherë kufiza e
(n +1)-të gjendet duke përdorur formulën rekursive an+1 = an ⸱q. Të shkruhen katër kufizat
e para të vargut gjeometrik, kufiza e parë e të cilit është a1 = 3 dhe herësi q = 2.
1, 𝑛 = 1
b. 𝑎𝑛+1 = {
3𝑎𝑛 , 𝑛 > 1
3 𝑛≤3
b. 𝑓2 (𝑛) = { 3 ∗ 𝑓 (𝑛 − 1)
2 𝑛≥4
0 𝑛=0
c. 𝑓3 (𝑛) = {𝑓 (𝑛 + 1) ∗ 𝑓 (𝑛)
3 3 𝑛>0
6. Të hartohet një algoritëm, që kur jepet shuma e një depozitë dhe interesi vjetor, të mund të
llogaritë se sa do të bëhet shuma e depozitës pas n vitesh.
7. Të hartohet një algoritëm rekursiv dhe një algoritëm iterativ që llogarit kufizën e n-të të
vargut {-4, 1, 6, 11, …}.
8. Të hartohet një algoritëm rekursiv dhe një algoritëm iterativ që llogarit kufizën e n-të të
vargut {3, 9, 27, 81, ...}.
9. Të hartohet një algoritëm rekursiv dhe një algoritëm iterativ që llogarit shumën 𝑆=
∑𝑛𝑖=1(𝑎 − 𝑖/𝑎)
10. Të hartohet një algoritëm rekursiv që kur jepen dy numra të plotë m dhe d, llogarit shumën
e të gjithë numrave të plotë të përfshirë ndërmjet tyre dhe pa përfshirë kufijtë.
11. Nëse n është një numër i plotë pozitiv çfarë afishon algoritmi i mëposhtëm?
mister(n) {
if (n = 0)
then print ("Fund")
else { print (n);
return mister (n – 1)
}
}
12. Të hartohet një algoritëm rekursiv që llogarit kufizën e n-të vargut të përcaktuar nga
kushtet: a0 = 1, a1 = 2, a2 = 3 dhe an = an-1 + an-2 + an-3 për n = 3, 4, 5…
13. Të hartohet një algoritëm rekursiv që kontrollon nëse një numër i dhënë natyror n ≥ 2 është
numër i thjeshtë?
Udhëzim. Të bazohemi tek idea që të kontrollojmë numrat nga 2 deri tek √ 𝑛 e numrit të
dhënë. Nëse mbetja e pjesëtimit është 0 do të thotë që numri nuk është i thjeshtë. Nëse
mbetja e pjesëtimit është e ndryshme nga zero vazhdojmë me numrin pasardhës (me kusht
që të jetë më i vogël se √ 𝑛 ).
14. Të afishohen vlerat e një array me n elemente duke përdorur instruksionin print.
15. Në një array janë vendosur n karaktere. Të hartohet një algoritëm rekursiv që llogarit se sa
herë shfaqet karakteri c në array.
16. Në një array janë vendosur n karaktere. Kërkohet të hartohet një algoritëm rekursiv që i
vendos karakteret në radhitjen e anasjelltë (Për shembull, përmbajtja “ABC”, do të kthehet
në “CBA”.
17. Në një array janë vendosur n karaktere. Të hartohet një algoritëm që kthen si përgjigje true
nëse karakteret formojnë një palindromë dhe false në të kundërtën. Një varg me karaktere
quhet palindromë nëse kur lexohet nga e majta në të djathtë po ashtu kur lexohet nga e
djathta në të majtë, kuptimi është i njëjtë, për shembull, fjala “radar” është palindromë).
18. Jepet një array a me n numra të plotë. Të hartohet një algoritëm rekursiv që gjen vlerën më
të vogël.
19. Hartoni një algoritëm që gjen vlerën më të madhe, në një array e përmasës n me numra të
plotë.
20. Të hartohet një algoritëm rekursiv që llogarit shumën e n elementeve të vendosur në një
array.
21. Të hartohet një algoritëm rekursiv që kopjon një array a me n elemente në një array tjetër
b me të njëjtën përmasë.
22. Jepet një array me n elemente. Të hartohet një algoritëm rekursiv që llogarit më të voglën
nga diferencat në vlerë absolute ndërmjet një elementi dhe paraardhësit të tij (duke
përjashtuar të parin).
23. Jepet një array me n elemente. Të hartohet një algoritëm që llogarit më të madhen nga
shumat ndërmjet një elementi dhe pasardhësit të tij (duke përjashtuar të fundit).