0% au considerat acest document util (0 voturi)
455 vizualizări17 pagini

Metoda Divide Et Impera (DEI)

Documentul prezintă algoritmul de căutare binară pentru găsirea unui element într-un vector ordonat. Algoritmul împarte vectorul în două părți egale și testează elementul din mijloc, continuând căutarea în prima sau a doua parte în funcție de valoarea elementului căutat.

Încărcat de

Iulia Nicoleta
Drepturi de autor
© © All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca PDF, TXT sau citiți online pe Scribd
0% au considerat acest document util (0 voturi)
455 vizualizări17 pagini

Metoda Divide Et Impera (DEI)

Documentul prezintă algoritmul de căutare binară pentru găsirea unui element într-un vector ordonat. Algoritmul împarte vectorul în două părți egale și testează elementul din mijloc, continuând căutarea în prima sau a doua parte în funcție de valoarea elementului căutat.

Încărcat de

Iulia Nicoleta
Drepturi de autor
© © All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca PDF, TXT sau citiți online pe Scribd

Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

Metoda Divide-et-impera (DEI)


DEI este o tehnică, în general, recursivă (deşi vom prezenta şi soluţii iterative ale metodei) care constă în
următoarele:
1. Dacă problema este rezolvabilă în mod direct (imediat), atunci ea se rezolvă;
2. Altfel, se descompune în două sau mai multe subprobleme mai simple, de aceeaşi natură cu problema iniţială,
subproblemele rezolvându-se prin aceeaşi metodă.
3. Soluţia problemei iniţiale se obţine prin combinarea soluţiilor subproblemelor.
Prezentăm, în continuare, câteva aplicaţii ale acestei metode.

Determinarea minimului sau maximului unui şir de numere


Să rezolvăm problema pentru determinarea minimului dintre elementele unui vector.
Notăm “încep” şi “sf” poziţiile de început, respectiv de sfârşit din vectorul în care se face căutarea.
Problema este rezolvabilă direct dacă numărul de elemente dintr-un vector sau subvector este <= 2, adică
"încep" = 1 şi "sf" <= 2.
Observăm că sf – încep <= 1. Se compară elementele de pe poziţiile "încep" şi "sf" şi se determină minimul.
Dacă problema nu este rezolvabilă direct, atunci ea se descompune în următoarele subprobleme:
1 - Se determină minimul primei jumătăţi a vectorului - fie acesta m1;
2 - Se determină minimul celei de-a doua jumătăţi a vectorului - fie acesta m2;
3 - Minimul final va fi cel mai mic dintre m1 şi m2. Desigur, determinările lui m1 şi m2 se fac recursiv.
De exemplu, fie vectorul X = (2, 5, 4, 1, 7, 6, 8, 3). Acesta se va împărţi în doi subvectori (2, 5, 4, 1) şi
(7, 6, 8, 3). Primul se va împărţi, la rândul său, în (2, 5) şi (4, 1). De aici rezultă două elemente minime,
corespunzătoare celor două părţi: 2 şi 1. Minimul din (2, 5, 4, 1) va fi, aşadar, numărul m1 = 1.
Cu cea de-a doua jumătate se procedează la fel, obţinându-se minimul m2 = 3. Se compară cele două valori,
rezultând numărul m1 = 1 ca minim al întregului vector.
START

Definim funcţia MINIM ( încep, sf: integer; X : vector )

DA NU
Sf – încep <= 1

mij := (încep + sf) DIV 2


DA NU
M 1 := MINIM ( încep, mij, X )
X [încep] < X [sf]

MINIM := X [ încep ] MINIM := X [ sf ] M 2 := MINIM ( mij + 1, sf, X )

DA M1<M2 NU

MINIM := M 1 MINIM := M 2

Main

Introduceti n (nr. elem. vector)

Introduceti elementele vectorului, X [ i ], pt. i = 1 . . n

min := MINIM ( 1, n, X )

Tipăreşte min

STOP
1
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
program Determinare_Minim;
uses CRT;
type
vector = array [1 .. 10] of REAL;
VAR
x : vector;
min : REAL;
n, i : integer;

function MINIM ( x : vector; încep, sf : integer ) : REAL;


var
mij : integer;
m1, m2 : REAL;
begin
IF sf - încep = 1 then
begin
if x [încep] < x [sf] then
MINIM := x [încep]
else
MINIM := x [sf]
end
ELSE
begin
mij := (încep + sf) DIV 2;
m1 := MINIM (x, încep, mij);
m2 := MINIM (x, mij, sf);
if m1 < m2 then
MINIM := m1
else
MINIM := m2
end;
end; {sf. funcţie}

begin {Main}
CLRSCR;
writeln (‘Precizati cate elemente are vectorul’);
write ('n = ');
readln (n);

writeln (‘Dati elementele vectorului x’);


for i := 1 to n do
begin
write ('x [ ',i,' ] = ');
readln (x [i]);
end;
min := MINIM (x, 1, n);
writeln;
writeln ('Min = ',min);
readln
end.
Acest algoritm se poate adapta şi pentru determinarea MAXIMULUI dintre elementele unui vector.

2
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

10. 2. Căutarea binară (Binary Search)


Problema cere să se verifice dacă un număr se află printre elementele unui şir (vector) ordonat crescător.
Căutarea secvenţială a numărului (care presupune parcurgerea vectorului de la început până la sfârşit) nu
este prea eficientă, deoarece, dacă numărul se află în a doua jumătate a vectorului, ar fi de preferat să nu-l căutăm în
prima jumătate. De aceea, îl vom căuta în a doua jumătate în care, în mod logic, s-ar putea găsi. De asemenea, dacă
numărul căutat se află printre primele elemente ale vectorului, nu mai are sens să se piardă timp cu testarea
următoarelor elemente, până la sfârşitul vectorului, deoarece sigur elementul nu va mai fi găsit (presupunem un
vector cu elemente distincte, ordonate crescător). Chiar dacă vectorul are toate elementele egale, este suficient doar
să precizăm dacă elementul căutat există sau nu, deci este suficientă o singură detectare a elementului.
Algoritmul căutării binare este:
- dacă numărul căutat este egal cu numărul din mijlocul vectorului, numărul căutat s-a găsit şi oprim căutarea;
- dacă numărul căutat este mai mic decât numărul din mijlocul vectorului, atunci căutăm în prima jumătate;
- dacă numărul căutat este mai mare decât numărul din mijlocul vectorului, atunci căutăm în a doua jumătate;
- căutarea în jumătatea aleasă se face în acelaşi mod, deci se va împărţi şi această jumătate ş.a.m.d.
Observaţie: Acest procedeu este mai rapid decât cel al căutării secvenţiale, dar nu se poate aplica decât dacă
vectorul este deja ordonat.

10. 2. a. Căutare binară – Varianta iterativă – Fără subprogram


START

Introduceti n (nr. de elemente ale vectorului)

Introduceti elementele vectorului, X [ i ], pt. i = 1 . . n

Introduceti elem ( elementul căutat )

Incep := 1

Sf := n

GASIT := FALSE

DA Incep <= Sf NU
SI
GASIT = FALSE
mij := ( Incep + Sf ) DIV 2

DA NU
Elem = X [mij]

GASIT := TRUE DA Elem < X [ mij ] NU

Sf := mij – 1 Incep := mij + 1

DA NU
GASIT = TRUE

Tipăreste “Elem există” Tipăreste “Elem NU există”

STOP

3
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
Program Căutare_Binară_Iterativă_Fără_Subprogram ;
CONST
Nmax = 100;
type
vector = array [1.. Nmax] of REAL;
VAR
x : vector;
mij, n, i, încep, sf : integer;
elem : REAL;
GASIT: boolean; { GASIT = TRUE dacă elementul a fost găsit şi FALSE, dacă nu}

Begin
CLRSCR;
REPEAT
Write (‘Dati numarul de elemente ale vectorului, n = ’);
readln (n);
UNTIL (n >= 1) AND (n <= Nmax);

writeln (‘Introduceti vectorul ordonat crescator’);

for i := 1 to n do
begin
write ('x [ ', i,' ] = ');
readln (x [i]);
end;
writeln;

write ('Daţi elementul căutat, elem = ');


readln (elem);

încep := 1;
sf := n;
GASIT:= FALSE;
while (încep <= sf) AND (GASIT = FALSE) do
begin
mij := (încep + sf) DIV 2;
if elem = x [mij] then
GASIT := TRUE
else
if elem < x [mij] then
sf := mij - 1
else
încep := mij + 1
end; {sfârşit WHILE}
if GASIT = TRUE then {sau if GASIT then}
writeln (elem,' există')
else
writeln (elem,' nu există');
readln
end.

4
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

10. 2. b. Căutare binară - varianta recursivă

START

Def. procedura CAUTA ( Incep, Sf : integer; VAR GASIT : Boolean )


DA NU
Incep <= Sf

mij := ( Incep + Sf ) DIV 2

GASIT := FALSE
DA NU
Elem = X [mij]

DA NU
GASIT := TRUE Elem < X [ mij ]

CAUTA (Incep, mij – 1, GASIT) CAUTA ( mij + 1, Sf, GASIT )

Main

Introduceti n (nr. de elemente ale vectorului)

Introduceti elementele vectorului, X [ i ], pt. i = 1 . n

Introduceti elem ( elementul căutat )

CAUTA ( 1, n, GASIT )

DA NU
GASIT = TRUE

Tipăreste “Elem există” Tipăreste “Elem NU există”

STOP

5
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
program Căutare_Binară_Varianta_Recursivă;
uses CRT;
CONST
Nmax = 100;
type
vector = array [1.. Nmax] of REAL;
VAR
x : vector ;
elem : REAL ;
n, i : integer ;
GASIT : boolean ; {GASIT = TRUE dacă elementul a fost găsit şi FALSE dacă nu}
procedure CAUTA ( încep, sf : integer; VAR GASIT : boolean ) ;
var
mij : integer;
begin
IF încep <= sf then
begin
mij := (încep + sf) DIV 2;
if elem = x [mij] then
GASIT := TRUE
else
if elem < x [mij] then
CAUTA ( încep, mij-1, GASIT)
else
CAUTA (mij +1, sf, GASIT)
end
ELSE
GASIT := FALSE
end; {sfârşit procedură}
begin {Main}
CLRSCR;
REPEAT
Write (‘Dati numărul de elemente ale vectorului, n = ’);
readln (n);
UNTIL (n >= 1) AND (n <= Nmax);
writeln (‘Introduceti vectorul ordonat crescator’);
for i := 1 to n do
begin
write ('x [ ', i,' ] = ');
readln (x [i]);
end;
writeln;
write ('Daţi elementul căutat, elem = ');
readln (elem);
CAUTA (1, n, GASIT);
if GASIT = true then
writeln (elem,' există')
else
writeln (elem,' nu există');
readln
end.

6
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

10. 3. Interclasarea
Se dau doi vectori A (m) şi B (n) ordonaţi. Să se interclaseze (să se construiască un al treilea vector
C (m + n), ordonat, care conţine toate elementele vectorilor A şi B).
Prezentăm doi algoritmi de interclasare asemănători.
START
Interclasare - Varianta 1
Introduceti m, n ( nr. de elemente ale vectorilor A şi B )

Introduceti elementele A [ i ], pt. i = 1 . . m

Introduceti elementele B [ j ], pt. j = 1 . . n

K := 0

i := 1
20 10 j := 1 30

DA NU
A [ i ] <= B [ j ]

K := K + 1 K := K + 1

C [ k ] := A [ i ] C [ k ] := B [ j ]

40 50 j := j + 1
i := i + 1

NU DA j > n NU
i <= m

DA j <= n NU DA i <= m NU
K := K + 1 K := K + 1

C [ k ] := B [ j ] C [ k ] := A [ i ]

j := j + 1 i := i + 1

60
K := 1

DA NU
K <= m + n
Tipăreşte C [ K ] STOP

K := K + 1

7
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
Program INTERCLASARE_1 ;
Label 10, 20, 30, 40, 50, 60 ;
Const nmax = 50;
Type vector = array [1 .. nmax] of REAL;
Var A, B : vector;
C : array [1 .. 2 * nmax] of REAL;
i, j, m, n, k : integer;
Begin
REPEAT
write ('Introduceţi m = '); readln (m);
UNTIL (m >= 1) AND ( m <= Nmax);
REPEAT
write ('Introduceţi n = '); readln (n);
UNTIL (n >= 1) AND ( n <= Nmax);
writeln (‘Dati vectorul A’);
for i := 1 to m do
begin
write ('A [i] = '); readln (A [i] )
end;
writeln (‘Dati vectorul B’);
for j := 1 to n do
begin
write ('B [j] = '); readln (B [j])
end;
k := 0; {index pentru elementele lui C}
i := 1; {index pentru elementele lui A}
j := 1; {index pentru elementele lui B}
10: if A [i] <= B [j] then
GOTO 20
else
GOTO 30;
20: k := k + 1; C [k] := A [i]; i := i + 1;
if i <= m then
GOTO 10
else
GOTO 40;
30: k := k + 1; C [k] := B [j]; j := j + 1;
if j > n then
GOTO 50
else
GOTO 10;
40: while j <= n do
begin
k := k + 1; C [k] := B [j]; j := j + 1;
end;
GOTO 60;
50: while i <= m do
begin
k := k + 1; C [k] := A [ i ]; i := i + 1;
end;
60: writeln (‘Vectorul rezultant este:’);
for k := 1 to m + n do
writeln ('C [',k,'] = ', C [k]); readln
end.
Observaţie: Varianta 1 a algoritmului de interclasare este mai greu de urmărit, datorită folosirii
instrucţiunii GOTO.

8
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
Iată şi o variantă mai clară, mai bine structurată a algoritmului de interclasare.
Interclasare - Varianta 2
START

Introduceti m, n ( nr. de elemente ale vectorilor A şi B )

Introduceti elementele A [ i ], pt. i = 1 . . m

Introduceti elementele B [ j ], pt. j = 1 . . n

K := 0

i := 1

j := 1

i <= m
DA NU
SI
j <= n

DA NU DA
A[i]<=B[j] i <= m NU

K := K + 1 K := K + 1 K := K + 1

C [ k ] := A [ i ] C [ k ] := B [ j ] C [ k ] := A [ i ]
DA j <= n NU
i := i + 1 j := j + 1 i := i + 1

K := K + 1

C [ k ] := B [ j ]

j := j + 1

K := 1

DA K <= m + n NU

Tipăreşte C [ K ] STOP

K := K + 1

9
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
program INTERCLASARE_2;
const Nmax = 30;
type vector = array [1 .. Nmax] of REAL;
var A, B : vector;
C : array [1 .. 2 * Nmax] of REAL;
i, j, m, n, k : integer;
begin
REPEAT
write ('Introduceti nr. de elemente pentru vectorul A, m = '); readln (m);
UNTIL (m >=1) AND (m <= Nmax);
REPEAT
write ('Introduceti nr. de elemente pentru vectorul B, n = '); readln (n);
UNTIL (n >=1) AND (n <= Nmax);

writeln ('Dati elementele vectorului A in ordine CRESCATOARE');


for i := 1 to m do
begin
write ('A [i] = '); readln (A [i] )
end;

writeln ('Dati elementele vectorului B in ordine CRESCATOARE');


for j := 1 to n do
begin
write ('B [j] = '); readln (B [j])
end;
k := 0; {index pentru elementele lui C}
i := 1; {index pentru elementele lui A}
j := 1; {index pentru elementele lui B}

WHILE ( i <= m ) AND ( j <= n) do


begin
if A [i] < B [j] then
begin
k := k + 1;
C [k] := A [i];
i := i + 1
end
else
begin
k := k + 1;
C [k] := B [j];
j := j + 1
end;
end;
WHILE i <= m DO
begin
k := k + 1;
C [k] := A [i];
i := i + 1
end;
WHILE j <= n DO
begin
k := k + 1;
C [k] := B [j];
j := j + 1
end;
writeln ('Vectorul rezultant C este:');
for k := 1 to m + n do
writeln ('C [k] = ', C [k])
readln
end.

10
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

10. 4. Sortarea prin interclasare - MERGE SORT


Se bazează tot pe metoda Divide-et-impera. Fiind dat un vector nesortat A [n], pentru a-l sorta,
împărţim vectorul în două, sortăm în mod identic cele două părţi ale vectorului, apoi le interclasăm. Dacă şi
subvectorii rezultaţi după împărţire sunt destul de mari (au mai mult de un două elemente), atunci împărţim
şi aceşti subvectori etc.
Vom declara o procedură ORDONEAZA care va sorta cele două “jumătăţi” ale vectorului.
Procedura va determina poziţia de mijloc şi se va autoapela pentru intervalul (început, mijloc), apoi
pentru intervalul (mijloc + 1, sfârşit), după care, apelând o a doua procedură INTERCLASEAZA, se vor
interclasa cele două părţi ale vectorului.

program MERGE_SORT;
CONST Nmax = 50;
TYPE vector = array [1 .. Nmax] of REAL;
VAR
n, i: integer;
A, : vector;
procedure INTERCLASEAZA (încep, mij, sf : integer; var A: vector );
var
i, j, k : integer ;
C : vector ; { C = vector auxiliar folosit în procedură }
begin
i := încep; { index pentru elementele primei jumătăţi a vectorului A }
j := mij + 1; { index pentru elementele celei de-a doua jumătăţi a vectorului A }
k := 0; { index pentru elementele vector auxiliar C }
while ( i <= mij ) AND ( j <= sf ) do
begin
if A [i] <= A [j] then
begin
k := k + 1;
C [k] := A [i];
i := i + 1;
end
else
begin
k := k + 1;
C [k] := A [j];
j := j + 1
end;
end;
while i <= mij do
begin
k := k + 1;
C [k] := A [i];
i := i + 1
end;
while j <= sf do
begin
k := k + 1;
C [k] := A [j];
j := j + 1
end;

11
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
k := 1;
for i := încep to sf do { REFACERE vector A SORTAT }
begin
A [i] := C [k] ;
k := k + 1
end;
end; { sfârşit procedură }

procedure ORDONEAZA (încep, sf : integer; var A : vector) ;


var
aux, mij : integer;
begin
if sf - încep <= 1 then
begin
if A [încep] > A [sf] then
begin
aux := A [încep] ;
A [încep] := A [sf] ;
A [sf] := aux
end
end
else
begin
mij := (încep + sf) DIV 2;
ORDONEAZA ( încep, mij, A );
ORDONEAZA ( mij + 1, sf, A );
INTERCLASEAZA ( încep, mij, sf, A );
end;
end; { sfârşit procedură }
begin {MAIN}
clrscr;
REPEAT
write ('Dati numarul elementelor, n = ');
readln (n);
UNTIL ( n >= 1 ) AND (n <= Nmax);
writeln;
writeln (‘Dati elementele vectorului’);
for i := 1 to n do
begin
write (' A [', i,'] = ');
readln (A [i]);
end;
ORDONEAZA ( 1, n, A ) ;
for i := 1 to n do
writeln ('A [', i,'] = ', A [i]);
readln
end.

12
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

START

Def. procedura INTERCLASEAZA ( Încep, mij, Sf : integer; VAR A : vector )

i := Încep Index/Contor pentru prima jumătate a vectorului

j := mij + 1 Index/Contor pentru a doua jumătate a vectorului

K := 0 Index/Contor pentru vectorul rezultant

i <= mij
SI NU
j <= sf

DA NU DA
A[i]<=A[j] i <= mij NU

K := K + 1 K := K + 1 K := K + 1

C [ k ] := A [ i ] C [ k ] := A [ j ] C [ k ] := A [ i ]
DA j <= sf NU
i := i + 1 j := j + 1 i := i + 1
K := K + 1

C [ k ] := A [ j ]

j := j + 1

K := 1

i := Încep

DA i <= sf NU

REFACEREA
VECTORULUI A [ i ] := C [ K ] Sf. proc
A ORDONAT
K := K + 1

i := i + 1

Se observă că procedura INTERCLASEAZĂ respectă algoritmul 2 de INTERCLASARE,


numai că, în procedură, nu avem doi vectori A şi B, ci jumătăţile (stângă şi dreaptă) ale vectorului A.

13
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
Def. procedura ORDONEAZA ( Încep, Sf : integer; VAR A : vector )

DA NU
Sf – Încep <= 1

DA A [ Încep ] > A [ Sf ] NU Mij := ( Încep + Sf ) DIV 2

ORDONEAZA ( Încep, mij, A )


AUX := A [ Încep ]

A [ Încep ] := A [ Sf ] ORDONEAZA ( mij + 1, Sf, A )

A [ Sf ] := AUX
INTERCLASEAZA ( Încep, mij, Sf, A )

Sf. proced.

Main

Introduceţi n ( nr. de elemente ale vectorului )

Introduceţi elementele vectorului, A [ i ], pt. i = 1 .. n

ORDONEAZA ( 1, n, A)

Tipăreşte vectorul sortat, A [ i ], pt. i = 1 .. n

STOP

10. 5. Sortarea rapidă - QUICK SORT


Este un alt exemplu de utilizare a tehnicii Divide-et-impera. Algoritmul (unul dintre cei mai eficienţi, creat
de profesorul Charles Anthony “Tony” Richard Hoare, în 1960) presupune raportarea la o poziţie “i” din interiorul
vectorului, poziţie situată între Încep şi Sf, astfel încât:
- toate elementele de pe poziţiile dintre Încep şi i – 1 să fie <= X [ i ]
- toate elementele de pe poziţiile dintre i + 1 şi Sf să fie >= X [ i ]
Se va folosi o procedură QUICK ( Încep, Sf ), care se va autoapela pentru cele două părţi rămase nesortate:
- anterioară elementului X[i]
- posterioară elementului X [ i ].
Se vor compara, în mod repetat, câte două elemente din vector de pe două poziţii i şi j.
Iniţial, i = Încep (prima poziţie din vector, respectiv 1), iar
j = Sf (ultima poziţie din vector, respectiv n).
La fiecare pas, dacă X [ i ] > X [ j ] se interschimbă
X [ i ] <-----------> X [ j ]
lucru urmat fie de mărirea lui i cu 1 ( i := i + 1), fie de micşorarea lui j cu 1 ( j := j – 1).
În acest fel, până când i devine egal cu j, poziţiile i şi j se apropie una de alta, odată cu efectuarea
eventualelor interschimbări impuse de relaţia dintre elementele X [ i ] şi X [ j ], corespunzătoare celor două
poziţii.
14
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs

START

Def. procedura QUICK ( Încep, Sf : integer; VAR X : vector )

DA NU
Încep < Sf Dacă Început = Sf, nu
Atenţie ! are sens interschimbarea
“Strict mai mare”. i := Încep X [ Încep ] <-> X [ Sf ].
În caz contrar, Deci, algoritmul va
“Stack overflow”. j := Sf continua doar dacă
Încep < Sf.
B := TRUE Condiţia de oprire ar
trebui să fie scrisă
Încep >= Sf
dar este scrisă
DA NU
X[i] > X[j] Încep < Sf
pentru a avea ramura
AUX := X [ i ] “DA” a IF-ului ocupată.

X [ i ] := X [ j ]

X [ j ] := AUX

B := NOT B
Xi > Xj
Xi < X j Se interschimbă Xi <-> Xj,
Se păstrează i se ocupă o poziţie i şi se
şi se alege alt j DA NU trece la următorul i
B = TRUE

j := j – 1 i := i + 1

DA i = j NU
i<j

QUICK (Încep, i , X )

QUICK ( i + 1, Sf, X )

Main

Introduceţi n ( nr. de elemente ale vectorului )

Introduceţi elementele vectorului, X [ i ], pt. i = 1 . . n

QUICK ( 1, n, X )

Tipăreşte vectorul sortat, X [ i ], pt. i = 1 . . n

STOP

15
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
Program QUICK_SORT;
CONST Nmax = 50;
TYPE vector = array [1 .. Nmax] of REAL;
VAR x : vector;
i, n : integer;
procedure QUICK (Încep, Sf : integer; VAR X : vector);
VAR
i, j : integer;
aux : REAL;
B : BOOLEAN;
begin
if Încep < Sf then {Conditia de oprire}
begin
i := Încep;
j := Sf;
B := TRUE;
repeat
if X [ i ] > X [ j ] then
begin
aux := X [ i ];
X [ i ] := X [ j ];
X [ j ] := aux;
B := not B;
end;
if B = TRUE then
j := j - 1
else
i := i + 1;
until i = j;
QUICK ( Încep, i, X );
QUICK ( i + 1, Sf, X );
end;
end;
begin {Main}
repeat
write ('n = '); readln (n)
until ( n >= 1) and (n <= Nmax);
write ('Introduceţi elementele vectorului');
for i := 1 to n do
begin
write (' X [ ', i, ' ] = '); readln ( X [ i ] );
end;
writeln ('Vectorul iniţial :');
for i := 1 to n do
write ( X [ i ],' ');
QUICK ( 1, n, X );
writeln ('Vectorul sortat este :');
for i := 1 to n do
write ( X [ i ],' ');
readln;
end.

16
Cătălin Tănase Algoritmi şi limbaje de programare - Note de curs
În Anexa 3 sunt prezentate alte aplicaţii ale metodei DEI: Problema tăieturilor, Suma elementelor unui
vector.

Concluzii
Metoda de programare Divide et Impera (“Dezbină şi stăpâneşte” – principiul de guvernare
enunţat de Machiavelli în formularea Divide Ut Regnes – „dezbină pentru a domni”) constă în
împărţirea unei probleme iniţiale de o anumită dimensiune în două sau mai multe subprobleme de
acelaşi tip şi de dimensiuni mai reduse. Se presupune că fiecare dintre problemele în care a fost
descompusă problema iniţială se poate descompune în alte subprobleme, la fel cum a fost descompusă
problema iniţială, sau se reduc la o problemă banală. Împărţirea în subprobleme are loc până când
dimensiunea acestora devine suficient de mică pentru a fi rezolvate în mod direct (cazul de bază,
probleme care admit o rezolvare imediată). După rezolvarea subproblemelor, se execută faza de
combinare a rezultatelor, în vederea rezolvării întregii probleme.
Metoda Divide Et Impera se poate aplica în rezolvarea unei probleme care îndeplineşte
următoarele condiţii:
1. problema iniţială se poate descompune în două sau mai multe subprobleme ;
2. aceste subprobleme sunt independente una faţă de alta (o subproblemă nu se rezolvă pe baza alteia
şi nu foloseşte rezultatele celeilalte) ;
3. subproblemele sunt similare cu problema iniţială;
4. la rândul lor, subproblemele se pot descompune (dacă este necesar) în alte subprobleme mai simple;
5. aceste subprobleme simple se pot soluţiona imediat prin algoritmul simplificat.
Deoarece puţine probleme îndeplinesc condiţiile de mai sus, aplicarea metodei este destul de rară.
Complexitatea algoritmilor bazaţi pe metoda Divide et Impera este în general bună (de multe
ori pătratică, chiar n * log (n) sau logaritmică).
Etapele rezolvării unei probleme în cadrul acestei metode sunt :
descompunerea problemei iniţiale în subprobleme independente, similare problemei de bază, de
dimensiuni mai mici;
descompunerea treptată a subproblemelor în alte subprobleme din ce în ce mai simple, până când se
pot rezolva imediat, prin algoritmul simplificat;
rezolvarea subproblemelor simple;
combinarea soluţiilor găsite, pentru construirea soluţiilor subproblemelor de dimensiuni din ce în ce
mai mari ;
combinarea ultimelor soluţii determină obţinerea soluţiei problemei iniţiale.
Întrucât metoda este, în esenţă, recursivă, ea se implementează cel mai natural folosind
subprograme recursive. Dacă dorim, totuşi, o implementare iterativă, va trebui să folosim în program o
stivă pe care să o gestionăm explicit şi în care să încărcăm subproblemele apărute şi nerezolvate.

17

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