Sunteți pe pagina 1din 13

?? ?

?
Divide et impera

Algoritmi i tehnici de
programare

Divide et impera

Determinarea elementului maxim dintr-o mulime

Metod de rezolvare a unor probleme

Maxim(a, n)

Maxim(a, p, u)

Caracteristici probleme

x =

max
1]

Maxim(a, n-1)
x1 = Maxim(a, p, (p+u)/2)
pot
fi descompuse
cu=complexitate
mic
= x>a[n-1]
? x n
: probleme
a[n- x2
Maxim(a, mai
(p+u)/2+1,
de acelai tip / cu soluie cunoscut u)
descompunerea este finit problemmax
primitiv
/ condiie?de x1
terminare
= x1>x2
: x2
cte probleme?
cum se face mprirea?

Metoda
biseciei
rezolvarea noilor probleme
este
mai uoar
soluiile combinate soluia problemei iniiale

Descompunere propriu-zis / reducere

Divide et impera

Algoritm recursiv
Implementarea este de obicei recursiv
Forma general
S=
determin o modalitate de descompunere a problemei P => P1, P2, Pn
pentru fiecare i=1:n

aplic recursiv algoritmul, pentru rezolvarea problemei Pi => Si


S=S Si

Divide et impera

Exemple
Probleme de parcurgere
Problema turnurilor din Hanoi
Problema tieturilor
Probleme de cutare

secvenial / binar

Probleme de sortare
prin interclasare
prin inserare
rapid (quick sort)
metoda micorrii incrementului (Shell sort)

Divide et impera

Probleme de parcurgere

o mulime a, cu n elemente => P(a, 0, n)


P(a, i, n) se descompune n
prelucrare a[i]
P(a, i+1, n)

void parcurge(float *v, int i, int n)


{ if( i!=n )
{ printf("%7.2f ",v[i]);
parc(v,i+1,n);
}
}

Divide et impera

Problema turnurilor din Hanoi

H(n, S, D, I)
H(n-1, S, I, D)
mut un disc de pe S pe D
H(n-1, I, D, S)

void hanoi(int n, char s, char d, char i)


{ if(n>0)
{ hanoi(n-1,s,d,i);
Surs
Destinaie
Intermediar
printf("\nMuta un disc de pe %c pe %c",s,d);
hanoi(n-1,i,d,s);
}
}
hanoi( 5, a, b, c);

Divide et impera

1
3
4
2

void taietura(int **c, int x, int y, int a, int b,


int *xm,
int *ym,x,int
int *bm)
Problema
tieturilor
y, a,*am,
,b
c[2,n]
{ int i,gasit;
1:x,c[1,i]a,y+b-c[1,i]
for( i=gasit=0; (i<n)&&!gasit;
)
a
if((c[0][i]>x)&&(c[0][i]<x+a) && (c[1][i]>y)&&(c[1][i]<y+b))
y+b
2:x,ya,c[1,i]-y
gasit=1;
else
3:x,yc[0,i]-x,b
i++;
if(gasit)
4:c[0,i],yx+a-c[0,i],b
c[1,i] { taietura(x,c[1][i], a,b-c[1][i]+y, xm,ym,am,bm);
taietura(x,y,
a,c[1][i]-y,
xm,ym,am,bm);
taietura(x,y,
c[0][i]-x,b,
xm,ym,am,bm);
taietura(c[0][i],y, a-c[0][i]+x,b, xm,ym,am,bm); xmax,ymax
y}
amax=0,bmax=0
else
if(a*b>(*am)*(*bm))
{ *am=a;
*bm=b;
x
c[0,i]
x+a
*xm=x; *ym=y;
}
}

Divide et impera

Probleme de cutare
Secvenial problem de parcurgere (mulimi sortate sau

nesortate)
Mulime
nesortat

Binar (mulimi sortate)

Mulime sortat

C(x,a,a,p,i,u,n,poz)
poz)
C(x, a, i, n, poz)
C(x,
dacp>u
i==n
dac i==n || a[i]>x
dac
poz=-1
poz=-1
poz=-1
altfel
altfel
altfel
dac x==a[i]
dac x==a[i]
m=(p+u)/2
poz=i
dacpoz=i
x==a[m]
altfel
altfel
poz=m
C(x, i+1, n, poz)
C(x, i+1, n, poz)
altfel
daca x<a[m]
C(x, a, p, m-1, poz)
Nualtfel
exist
s se
obin poziia -1 chiar dac elementul
C(x, riscul
m+1, u,
poz)

cutat
se afl n mulime, deoarece n momentul gsirii lui, nu se mai
face nici un apel recursiv i nu se mai modific valoarea lui poz

Divide et impera

Sortare prin interclasare

S(0,14)
S(a, n) => S(a, 0, n-1)
15 dac
7 p<u
13 5 11
3
1
8 14
9 m=(p+u)/2
S(0,7)
S(a, p, m)
m+1, 5
u) 11
15 7S(a,13
3
1
8 14
2
9 interclaseaz a[p:m] cu a[m+1:u]

12

10

S(8,14)
6

12

10

1
12
1
14

3
14
2
15

11

13

15

10

10

11

12

13

Divide et impera

Sortare rapid
Q(0,n-1)

Q(x,
p,u)
x[0]
x[1]
x[2] x[k-2] x[k-1] x[k] x[k+1] x[k+2]
dac p<u
x[n-1]
Q(0,k-1)
Q(k+1,n-1)
poziionare(x,
p, u, k)
Q(x, p, k-1)
x[0] x[1]
x[2]
Q(x, k+1,
u) x[k-2] x[k-1] x[k] x[k+1] x[k+2]

x[n-1]

10

0 1

19

15

17

-1

Divide et impera

Sortare prin micorarea incrementului (Shell sort)


generalizare a sortrii prin inserie
vector k-sortat
secven de pai : valori descresctoare, ultima este 1
Algoritm
pentru fiecare pas din secven
pentru fiecare i=pas..n-1
j=i-pas
ct timp j>0 i v[j]<v[j+pas]
v[j] <->v[j+pas]
j-=pas

Divide et impera

Sortare prin micorarea incrementului (Shell sort)

indici
n=15
Initial:
Dupa pasul
7:
Dupa pasul
3:
Dupa pasul
1:

0
38
3
3
3

1
13
13
5
5

2
85
71
9
9

3
98
40
10
10

4
5
5
13
13

5
70
9
44
38

6
45
10
40
40

7
44
38
38
44

8
68
68
44
44

void sort_shell(double v[], int l)


{ int i,j,inc;
double a;

for(inc=l/2; inc>0; inc=inc/2)


for(i=inc; i<l; i++)
for(j=i-inc; (j>=0)&&(v[j]>v[j+inc]); j=j-inc)
{ a=v[j];
v[j]=v[j+inc];
v[j+inc]=a;
}
}

9
71
85
70
45

10
40
98
45
68

11
44
44
68
70

12
9
70
85
71

13
10
45
98
85

14
3
44
71
98

Spor la nvat!

S-ar putea să vă placă și