Академический Документы
Профессиональный Документы
Культура Документы
Andrzej Szepietowski
25 marca 2004 roku
Rozdzia 1
Rekurencja
1.1 Wieze Hanoi
Rekurencja jest to zdolnosc podprogramu (procedury lub funkcji) do wywoywania samego siebie. Zacznijmy od przykadu wiez Hanoi. Przypusc my, z e mamy trzy wieze lub
trzy paliki: A, B i C. Na pierwszym paliku, A, znajduja sie trzy kra
zki rznej wielkosci,
nanizane w porzadku
regu:
mozna przenosic po jednym kra
zku z jednego palika na inny,
nie mozna umieszczac wiekszego kra
zka na mniejszym.
Rozwiazaniem
A C,
B C,
A B,
C A,
C B,
A B,
A B,
przekadamy N 1 kra
zkw z A na pomocniczy palik C (posugujac
sie w
razie potrzeby palikiem B),
przekadamy N -ty kra
zek z A na B,
przekadamy N 1 kra
zkw z C na A (za pomoca palika B).
3
Rozdzia 1. Rekurencja
przenies(N 1 kra
zkw z X na Z, za pomoca Y ),
wypisz X Y ,
przenies(N 1 kra
zkw z Z na Y , za pomoca X).
2
AC
1
AB
2
CB
1
BC
1
CA
1
AB
Dziaanie procedury rekurencyjnej dobrze ilustruje tak zwane drzewo rekursji. Rysunek 1.1 8.1 przedstawia drzewo rekursji dla algorytmu przekadania trzech kra
zkw na
wiezach Hanoi. Wierzchoki odpowiadaja wywoaniom procedury. Skrt
N
XY
oznacza wywoanie procedury przenies(N kra
zkw z X na Y , za pomoca trzeciego palika ). W korzeniu wywoujemy procedure do przeozenia 3 kra
zkw z palika A na B. To
wywoanie samo dwa razy wywouje przenies: raz dla przeniesiena 2 kra
zkw z A na C i
drugi raz dla przeniesienia 2 kra
zkw z C na B, Tym wywoaniom odpowiadaja synowie
Jak widac definicja funkcji odwouje sie sama do siebie. Rysunek 1.2 przedstawia
drzewo rekursji dla obliczenia najwiekszego wsplnego dzielnika liczb 5 i 3. W tym przypadku drzewo jest zredukowane do jednej sciezki. Ponizej przedstawiono zawartosci stosu
rekursji po kazdym wywoaniu i zamknieciu funkcji.
[N W D(5, 3)]
[N W D(5, 3)] [N W D(2, 3)]
[N W D(5, 3)] [N W D(2, 3)] [N W D(2, 1)]
[N W D(5, 3)] [N W D(2, 3)] [N W D(2, 1)] [N W D(0, 1)]
[N W D(5, 3)] [N W D(2, 3)] [N W D(2, 1)]
[N W D(5, 3)] [N W D(2, 3)]
[N W D(5, 3)]
Rozdzia 1. Rekurencja
N W D(2, 3)
N W D(2, 1)
N W D(0, 1)
2a3d/ +
ktry jest postacia postfixowa wyrazenia 2(a + 3/d).
Istnieja jeszcze dwie inne pokrewne metody przeszukiwania drzew binarnych: inorder
i preorder:
2 a + 3/d
czyli wyrazenie w postaci infixowej, ale bez nawiasw. Przeszukanie tego samego drzewa
metoda preorder da ciag
etykiet:
2 + a/3d
Jest to tak zwana postac prefixowa wyrazenia. Znak operacji wystepuje w niej przed argumentami. Podobne jak w postaci postfixowej, postac prefixowa da sie jednoznacznie
rozkadac i nie wymaga nawiasw.
Rozdzia 1. Rekurencja
zbioru. Ponizej przedstawiamy rekurencyjny algorytmu wstawiania elementw do drzewa. W (x) oznacza wartosc przechowywana w wierzchoku x. Pamietajmy, z e Tx oznacza poddrzewo o korzeniu w wierzchoku x.
Algorytm wstawiania elementu do drzewa poszukiwan binarnych.
Aby wstawic element e do drzewa Tx :
jezeli drzewo Tx jest puste, to
W (x) := e (wstaw e do korzenia x),
w przeciwnym razie
porwnaj e z zawartoscia korzenia W (x):
jezeli e < W (x), to
wstaw e do poddrzewa Tx0 ,
jezeli e > W (x), to
wstaw e do poddrzewa Tx1 .
Przykad 1.3 Przypusc my, ze mamy ciag
liczb naturalnych:
128, 76, 106, 402, 100, 46, 354, 1018, 112, 28, 396, 35.
Utworzymy dla tego ciagu
drzewo poszukiwan binarnych.
Rysunek 1.4: Drzewo poszukiwan po wstawieniu elementw: 128, 76, 106, 402
128
76
402
106
Po wstawieniu pierwszych czterech elementw ciagu
otrzymamy drzewo, ktre jest
przedstawione na rysunku 1.4, a po wstawieniu caego ciagu
otrzymamy drzewo, ktre
jest przedstawione na rysunku 1.5. Jezeli teraz przeszukamy to drzewo metoda inorder, to
otrzymamy ten sam ciag,
ale uporzadkowany:
28, 35, 46, 76, 100, 106, 112, 128, 354, 396, 402, 1018.
128
76
402
46
28
106
100
354
112
1018
396
35
10
Rozdzia 1. Rekurencja
jezeli e > W (x), to
szukamy e w prawym poddrzewie Tx1 .
dwch rwna n :
silnia(0) = 1,
silnia(n) = n silnia(n 1),
dla n 1.
Podobnie mozna definiowac inne funkcje ze zbioru liczb naturalnych w zbir liczb naturalnych. Definicja taka zawiera przepis, jak policzyc wartosc funkcji dla wartosci poczat
kowych, oraz drugi przepis, jak wyliczyc wartosc dla argumentu n za pomoca wartosci
funkcji dla mniejszych argumentw.
,
(1.1)
5
rwnania x 2
2
2
n1
n2
x 1 = 0, mamy wiec + 1 = oraz + 1 = a takze
+
= n oraz
n1
n2
n
+
= . atwo teraz mozna pokazac, z e F (n) = F (n 1) + F (n 2) =
1 (n n ).
5
Poniewaz || < 1, mamy 15 n < 15 < 12 , wiec wartosc F (n) jest rwna 15 n po
zaokragleniu
11
Dla
prostoty zazmy, z e dugosc ciagu
jest potega dwjki.
Algorytm sortowania
jezeli ciag
ma dugosc jeden, to jest juz posortowany,
jezeli ciag
jest duzszy, to:
dzielimy go na poowy,
sortujemy te poowy,
aczymy
A = (1, 3, 6, 7),
B = (2, 4, 8, 9),
i z e chcemy je poaczy
c w posortowany ciag
C. Na poczatku
ciag
C jest pusty. Ustawiamy dwa wskazniki po jednym na poczatku
kazdego ciagu
(wskazane elementy beda
oznaczone daszkiem):
A = (
1, 3, 6, 7),
B = (
2, 4, 8, 9),
C = ().
2, 4, 8, 9),
B = (
C = (1).
A = (1, 3, 6, 7),
A = (1, 3, 6,
7),
A = (1, 3, 6, 7),
B
B
B
B
B
= (2,
4, 8, 9),
= (2,
4, 8, 9),
= (2, 4,
8, 9),
= (2, 4,
8, 9),
= (2, 4,
8, 9),
C
C
C
C
C
= (1, 2),
= (1, 2, 3),
= (1, 2, 3, 4),
= (1, 2, 3, 4, 6),
= (1, 2, 3, 4, 6, 7).
B = (2, 4, 8, 9),
C = (1, 2, 3, 4, 6, 7, 8, 9).
12
Rozdzia 1. Rekurencja
merge-sort(S):
jezeli S ma tylko jeden element, to koniec,
jezeli S ma wiecej elementw, to:
dzielimy ciag
S na poowy S1 i S2 ,
merge-sort(S1),
merge-sort(S2),
aczymy
S 1 i S2 .
61|84
3|7
5|2
7
37
6|1
2
25
8|4
1
16
2357
4
48
1468
12345678
Algorytm merge-sort jest przykadem algorytmu typu dziel i zwyciez aj, ktrego
oglny schemat wyglada
tak:
jezeli problem jest maego rozmiaru, to rozwiazujemy
go bezposrednio,
jezeli problem jest duzy, to:
dzielimy problem na podproblemy,
rozwiazujemy
podproblemy,
aczymy
rozwiazania
podproblemw w rozwiazanie
caego problemu.
1.9. Rozwiazywanie
13
1.9 Rozwiazywanie
T (1) = 0,
(1.2)
n
T (n) 2T ( ) + n.
2
(1.3)
dugosci n2 , a nastepnie potrzebujemy n porwnan , aby scalic te dwie powki. Dla prostoty rozwazan zakadamy tutaj, z e n jest potega dwjki, n = 2k dka jakiegos naturalnego
k.
Istnieje wiele sposobw wyliczania lub szacowania funkcji okreslonej rekurencyjnie.
Przedstawimy teraz dwa najprostsze z nich: metode podstawiania i metode iteracji.
,
(1.4)
F (n) =
5
ale tam odgadnieto dokadne rozwiazanie.
zaczynajac
od oglniejszej postaci. Zacznijmy od rwnania
F (n + 2) = F (n + 1) + F (n).
(1.5)
14
Rozdzia 1. Rekurencja
= 21 (1 + 5)2 oraz =
1
5)2, czyli dwie funkcje F1 (n) = n oraz F2 (n) = n speniaja rwnanie (1.5).
2 (1
Zauwazmy, z e takze kazda funkcja postaci
F (n) = c1 F1 (n) + c2 F2 (n)
gdzie c1 i c2 to stae, spenia rwnanie (1.5). Sprawdzmy teraz, dla jakich staych c 1 i c2
funkcja F spenia zaleznosci F (0) = 0 i F (1) = 1. Otrzymujemu ukad rwnosci
0 = c 1 + c2
1 = c 1 + c2
Powyzszy ukad jest speniony dla
c1
c2
1
1
=
( )
5
1
= c1 =
5
n n
,
5
(1.6)
=
=
n
n + 3T ( )
4
n
n
n + 3( + 3T ( ))
4
16
15
3
n
= n + n + 9T ( )
4
16
...
i1
n
3
3
+ 3i T ( i )
= n+n +...+n
4
4
4
Iteracje powtarzamy, az ostatni skadnik bedzie zawiera T (1), czyli gdy i = log 4 n.
Otrzymamy wtedy
i1
3
3
T (n) = n + n + . . . + n
+ 3i T (1)
4
4
i
X
3
+ 3log4 n = 4n + o(n) = O(n)
n
4
i=0
Skorzystalismy tu z rwnosci 3log4 n = nlog4 3 oraz z faktu, ze log4 3 < 1 i nlog4 3 = o(n).
Przykad 1.5 Jako drugi przykad rozwazmy rekursje
T (1) = 1
n
T (n) = 2T ( ) + n
2
Jak bedziemy ja rozwijac, to otrzymamy
T (n)
n
n + 2T ( )
2
=
=
...
=
n
n + n + 4T ( )
4
n + n + . . . + n + 2i T (
n
)
2i
T (n) = n
i=0
n
n + n2 + 16T ( )
4
n + n2 + . . . + n2i1 + 4i T (
n
)
2i
16
Rozdzia 1. Rekurencja
T (n) = n
X
i=0
(1.7)
rozwiaza
n podproblemw w rozwiazanie
caego problemu.
Na koniec podamy bez dowodu twierdzenie mwiace
jak mozna szacowac funkcje
T (n) okreslona rwnaniem (1.7).
Twierdzenie 1.7 (o rekurencji uniwersalnej) Niech T (n) bedzie okreslone dla nieujemnych liczb cakowitych rwnaniem rekurencyjnym
n
T (n) = aT ( ) + f (n),
b
gdzie a 1, b > 1 i
n
b
(a) Jezeli f (n) = O(nlogb a ) dla pewnej staej > 0, to T (n) = (nlogb a ).
(b) Jezeli f (n) = (nlogb a ), to T (n) = (nlogb a log n).
(c) Jezeli f (n) = (nlogb a+ ) dla pewnej staej > 0 oraz af ( nb ) cf (n) dla
pewnej staej c < 1, to T (n) = (f (n)).
Z pewnym uproszczeniem, powyzsze twierdzenie przedstawia rozwiazanie
w zaleznosci od wyniku porwnania funkcji f (n) i jednomianu nlogb a . W punkcie (a) funkcja
(n)
cn dla pewnych staych c i
f (n) rosnie wolniej niz nlogb a , a scislej, iloraz nflog
ba
> 0. Taka sytuacja jest w przykadzie 1.6, w ktrym a = 4, b = 2 oraz f (n) = n, a
rozwiazaniem
17
Przesledzmy
ta metode na przykadzie funkcji Fibinacciego. Rozwazmy funkcje okreslona szeregiem
potegowym.
G(z) = F (0) + F (1)z + F (2)z 2 + + F (n)z n +
(1.8)
(1.10)
W tym szeregu wyraz wolny wynosi F (0) = 0, wspczynnik przy z rwna sie F (1)
F (0) = 1, a wszystkie nastepne wspczynniki sa zerami poniewaz F (n) F (n 1)
F (n 2) = 0 dla kazdego n 2. Mamy wiec
G(z)(1 z z 2 ) = z
czyli
G(z) =
z
.
(1 z z 2 )
(1.11)
Jezeli rozwiniemy funkcje (1.11) w szereg, to wspczynniki tego rozwiniecia utworza ciag
Fibonacciego. Aby to zrobic, zauwazmy, z e funkcje G(z) mozna przedstawic
jako
z
1
1
1
G(z) =
,
=
(1 z z 2 )
1 z
5 1 z
gdzie oraz sa znanymi juz nam pierwiastkami wielomianu z 2 z 1. Funkcja
posiada rozwiniecie
X
1
=
ai z i ,
1 az
i=0
Wiec funkcja G(z) posiada rozwiniecie
G(z) =
a z tego mamy
X
1
(i i )z i ,
5
i=0
1
F (n) = (i i ).
5
1
1az
18
Rozdzia 1. Rekurencja
1.14 Zadania
1. Wypisz ciag
przeozen potrzebnych do przeniesienia czterech kra
zkw na wiezach
Hanoi.
2. Udowodnij, z e algorytm opisany w podrozdziale 8.1 wymaga 2 n 1 przeozen do
przeniesienia n kra
zkw.
3. Oblicz N W D(39, 24) wedug rekurencyjnego algorytmu Euklidesa.
4. Napisz program, ktry rekurencyjnie oblicza: a) funkcje silnia, b) funkcje Fibonacciego,
5. Napisz program, ktry oblicza symbol Newtona:
a) wedug wzoru rekurencyjnego
n+1
n
n
=
+
,
k
k
k1
b) wedug wzoru
n
n(n 1) (n k + 1)
.
=
k!
k
Porwnaj te programy.
6. Funkcja h okreslona jest nastepujacymi
rwnaniami:
h(0)
= 1,
h(n + 1) = 2 h(n) + 1.
Oblicz wartosci h(1), h(2), h(3), h(4), h(5). Udowodnij, z e h(n) = 2n+1 1.
7. Funkcja F okreslona jest nastepujacymi
rwnaniami:
F (0)
= 0,
F (1)
= 1,
F (n + 2) = 3 F (n + 1) F (n).
Oblicz wartosci F (2), F (3), F (4), F (5). Rozwia
z ulad rwnosci metoda podstawiania.
8. Wedug algorytmu aczenia
poacz
ciagi
a = (2, 5, 10, 13, 16, 23)
i b = (1, 3, 4, 7, 15, 20).
9. Stosujac
algorytm merge-sort posortuj ciag
(2, 5, 10, 13, 16, 23, 1, 3, 4, 7, 15, 20).
10. Stosujac
algorytm merge-sort posortuj ciag
sw: sowik, wrbel, kos, jaskka,
kogut, dziecio, gil, kukuka, szczygie, sowa, kruk, czubatka.
[Fragment wiersza Ptasie radio Juliana Tuwima]
1.14. Zadania
19
dla n 1.
dla n 1.
dla n 1.
20
Rozdzia 1. Rekurencja
ciagu
liczb: 30, 43, 13, 8,
50, 40, 20, 19, 22.
22. Narysuj drzewo poszukiwan binarnych dla nastepujacego
ciagu
sw: sowik, wrbel, kos, jaskka, kogut, dziecio, gil, kukuka, szczygie, sowa, kruk, czubatka.
[Fragment wiersza Ptasie radio Juliana Tuwima]
23. Zaprojektuj algorytm wyszukiwania najmniejszego elementu w drzewie poszukiwan binarnych.
24. Zaprojektuj algorytm, ktry dla wierzchoka z wartoscia x wyszukuje w drzewie
poszukiwan binarnych wierzchoka z nastepna wartoscia.
1.15 Problemy
1.15.1 Funkcja Ackermanna
Funkcja Ackermanna okreslona jest, dla liczb naturalnych i, j, k 1, nastepujacymi
rwnaniami:
A(1, j, k)
=j +k
A(i + 1, j, 1)
=j
A(i + 1, j, k + 1) = A(i, j, A(i + 1, j, k))
Funkcja Ackermanna jest przykadem funkcji majacej
dosc prosta definicje, ale jest
praktycznie nieobliczalna z tego powodu, z e jej wartosci szybko rosna.
1. Udowodnij, z e A(2, j, k) = j k oraz A(3, j, k) = j k .
2. Oblicz A(3, j, 1), A(3, j, 2), A(3, j, 3), A(3, j, 4).
1.15. Problemy
21
3. Udowodnij, z e
A(3, j, k) = j
k razy.