int silnia (int n) {
if (n==0) return 1;
return n*silnia(n-1);
}
Wyszukiwanie wzorca rekurencyjnie – iteracja
#include <iostream.h>
#include <stdlib.h>
const int n=10;
int tab[n]={1,2,3,2,-7,44,5,1,0,-3};
void szukaj(int tab[n],int left,int right,int x)
// left, right = lewa i prawa granica obszaru poszukiwań // tab = tablica
// x = wartość do odnalezienia {
if (left>right)
cout << "Element " << x << " nie został odnaleziony\n";
else
if (tab[left]==x)
cout << "Znalazłem szukany element "<< x << endl;
else
szukaj(tab,left+1,right,x);
}
int main() {
szukaj(tab,0,n-1,7);
szukaj(tab,0,n-1,5);
system("pause");}
// wyniki programu:
// Element 7 nie został odnaleziony // Znalazłem szukany element
Wyszukiwanie binarne wzorca –rekurencja
#include <iostream.h>
int szukaj_rec(int * tab, int x, int left, int right) {
if(left>right) return -1; // element nie znaleziony else
{
int mid=(left+right)/2;
if(tab[mid]==x)
return mid; // element został znaleziony!
else
if(x<tab[mid])
return szukaj_rec(tab,x,left,mid-1);
else
return szukaj_rec(tab,x,mid+1,right);
} }
int main() {
int tabl[12]={1,2,6,18,20,23,29,32,34,39,40,41};
cout << "wynik="<<szukaj_rec(tabl,23,0,11)<<endl;
system("pause");
}
int stad_do_wiecznosci (int n) {
if (n==1) return 1;
else
if (n%2==0)
return n*stad_do_wiecznosci (n-2) else
return n*stad_do_wiecznosci (n-1) }
---
float power (float x, int n) main() { {…
if (!n) /*136*/ y=power(5.6,2);
return 1; …
/*105*/ return x*power(x,n-1); }
Trzecie wywołanie power()
0WS 5,6 (105)
?
0WS 5,6 (105)
1
0 5,6 (105)
1 Drugie
wywołanie power()
1WS 5,6 (105)
?
1 5,6 (105)
?
1 5,6 (105)
?
1WS 5,6 (105)
?
1WS 5,6 (105)
5,6
1 5,6 (105)
5,6 Pierwsze
wywołanie power()
2WS 5,6 (136)
?
2 5,6 (136)
?
2 5,6 (136)
?
2 5,6 (136)
?
2 5,6 (136)
?
2 5,6 (136)
?
2WS 5,6 (136)
?
2WS 5,6 (136) 31,36 RW
funkcji main()
: y
:
: y
:
: y :
: y :
: y :
: y :
: y :
: y
: }
Co się dzieje na stosie?
Wersja nierekurencyjna float power(float x, int n) {
float wynik=1 if (n>0)
for (wynik = x; n>1; --n) wynik = wynik *x;
return wynik;
}
Rodzaje rekursji:
Rekursja końcowa
void tail(int i) void tail(int i) { {
if i>0 for (i; i>0; i--)
{ cout <<”A”;
cout <<”A”; } tail(i-1);
} }
Rekursja niekońcowa
Rekursja pośrednia
f( ) -> f1( ) -> f2( ) -> ... -> fn( ) -> f( )
Rekursja zagnieżdżona
4 0
)) 2 ( 2 (
4 0 0
) (
n dla
n h h
n dla n
n dla n
h
Liczby Fibonacciego Pierwsza wersja
int F(int i) {
if (i < 1) return 0;
if (i == 1) return 1;
return F(i-1) + F(i-2); przy obliczaniu F(20) 242 785 wywołań }
Druga wersja F[0]=0; F[1]=1;
for (i=2; i<=n; i++);
F[i] =F[i-1] + F[i-2];
I trzecia int F(int i) {
static int znaneF[maxN];
if (znaneF[i] != 0) return znaneF[i];
int t = i;
if (i < 0)
return 0;
if (i > 1)
t = F(i-1) + F(i-2);
return znaneF[i] = t;
}
Problem plecakowy
"This code is from "Algorithms in C++, Third Edition," by Robert Sedgewick, Addison-Wesley, 1999."
Implementacja rekurencyjna int knap(int cap)
{ int i, space, max, t;
for (i = 0, max = 0; i < N; i++)
if ((space = cap-items[i].size) >= 0)
if ((t = knap(space) + items[i].val) >
max)
max = t;
return max;
}
Programowanie dynamiczne
int knap(int M)
{ int i, space, max, maxi = 0, t;
if (maxKnown[M] != unknown) return maxKnown[M];
for (i = 0, max = 0; i < N; i++)
if ((space = M-items[i].size) >= 0)
if ((t = knap(space) + items[i].val) >
max)
{ max = t; maxi = i; }
maxKnown[M] = max; itemKnown[M] = items[maxi];
return max;
}
Wieże Hanoi void hanoi(int n, int d)
{
if (n == 0) return;
hanoi(n-1, -d);
shift(n, d);
hanoi(n-1, -d);
}
Linijka
void rule(int l, int r, int h) { int m = (l+r)/2;
if (h > 0) {
rule(l, m, h-1);
mark(m, h);
rule(m, r, h-1);
} }
void rule(int l, int r, int h) { int m = (l+r)/2;
if (h > 0) {
mark(m, h);
rule(l, m, h-1);
rule(m, r, h-1);
} } Bez rekurencji
void rule(int l, int r, int h) {
for (int t = 1, j = 1; t <= h; j += j, t++) for (int i = 0; l+j+i <= r; i += j+j) mark(l+j+i, t);
}
8 hetmanów ustaw (row)
{
dla każdej kolumny col w rzedzie row jeśli pozycja col nie jest atakowana
{
umieść hetmana na col;
jeśli row<8
ustaw (row + 1) w przeciwnym wypadku
wypisz rozwiązanie usuń hetmana z pozycji col }
}