Tải bản đầy đủ (.pdf) (16 trang)

thiết kế và đánh giá thuật toán - trần tuấn minh -3 pps

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.47 MB, 16 trang )

Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 33 -


CHƯƠN PG 2 : HƯƠNG PHÁP CHIA ĐỂ TRỊ
(Divide - and - conquer)
I. Mở đầu
1. Ý tưởng
Có lẽ q äng rãi nhất là kỹ thuật thiết kế “Chia để trò” .
Nó phân rã bài toán kích thước n thành các bài toán con nhỏ hơn mà việc tìm lời
giải cu là cùn ài toán đã cho được xây dựng từ lời
giải cu
hính của phương pháp này là : chia dữ liệu
thành từng miền đủ nhỏ, giải bài toán trên các miền đã chia rồi tổng hợp kết quả
lại.
2. Mô hình
uan trọng và áp dụng ro
ûa chúng g một cách. Lời giải của b
các bûa ài toán con này .
Ta có thể nói vắn tắt ý tưởng c

D& (ℜ) - là miền dữ liệu - là hàm thể hiện cách giải bài
toán th o phươ g pha chia
void D&C(
ℜ)

i


ả;
}
}
huật thiết kế “ Chia để trò “ .
nhò phân.
Nếu gọi C Với ℜ
e n ùp để trò thì ta có thể viết :
{
If (
ℜ đủ nhỏ)
giải bài toán;
Else
{
Chia
ℜ thành ℜ
1
, …,ℜ
m
;
for (i = 1; i <=m; i++)
D&C(
);
Tổng hợp kết qu
Sau đây là các minh họa kỹ t
II. Thuật toán tìm kiếm
1. Phát biểu bài toán
hần tử đ Cho mảng n p ã được sắp tăng dần và một phần tử x. Tìm x có
ong m Nếu có x trong mảng thì cho kết quả là 1, ngược lại cho
kiếm nhò phân .
tr ảng hay không ?

kết quả 0.
oán tìm Giải bằng thuật t
2. Ý tưởng
Chia đôi mảng , mỗi lần so sánh phần tử giữa với x, nếu phần tử x nhỏ hơn
lấy nửa trái, ngược lại thì lấy nửa phải.
3. Mô tả thuật toán
thì

Input : a[1 n]
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 34 -


Output :


∈ ax;1


∉ ax;0
Mô tả :
Tknp(a, x, Đầu, Cuối)

If (Đầu > Cuối)

Giữa = (Đầu + cuối) / 2;
If (x == a[Giữa])
retu 1;
e
if (x > a[Giữa])
else
thời gian của thuật toán
return 0 ; {dãy trống}
Else
{

rn
lse
Tknp(a, x, Giữa + 1, Cuối) ;

Tknp(a, x, Đầu, Giữa - 1) ;
}
4. Độ phức tạp
nhất : tương ứng với sự tìm được x trong lần so sánh đầu
( x nằm ở vò trí giữa mảng ).
.
) Trường hợp xấu nhất : Độ phức tạp là O(lg n).
) là độ phức tạp của thuật toán , thì sau khi kiểm tra
điều kiện ( x == a[giữa]) và sai thì gọi đệ qui thuật toán này với dữ liệu giảm nửa,
nên thỏa mãn công thức truy hồi :
(n) =
≥ 2 và T[1] = 0.
5.
a) Trường hợp tốt
tiên, tức là : a[Giữa] == a[n/2] == x

Ta có : T
tốt
(n) = O(1)
b
Thật vậy, Nếu gọi T(n
T 1 + T[n/2] ; n
Cài đặt
int tknp(int a[max],int x,int l, int r)
{

( l > )
eturn






}

int mid;
if r
r 0;
m l+id = ( r)/2;
if ( x == a[mid] )
return 1;
if ( x > a[mid] )
r tknp(a,x,mid+1,r); eturn
return tknp(a,x,l,mid-1);
Trần Tuấn Minh Khoa Toán-Tin

Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 35 -


III. Bài toán MinMax

1. Phát biểu bài toán
Tìm giá trò in M , Max trong đoạn a[l r] của mảng a[1 n].
2. Ý tưởng
Tại mỗi bước, chia đôi đoạn cần tìm rồi tìm Min, Max của từng đoạn, sau đó
ång hơ lại k t quả.
có 1 phần tử thì Min = Max và bằng phần tử đó.
Minh họa :

6 7 8
to ïp ế
Nếu đoạn chia chỉ
i 1 2 3 4 5
a[i] 10 1 5 0 9 3 15 19

Min, Max trong đoạn a[2 7] của mảng a[1 7] .
Ký hiệu :
ax) cho Min và Max trong đoạn a[l r].
Cho Min = 0 và Max = 15 trong đoạn a[2 7]
3. Thuật toán

Tìm giá trò
MinMax(a,l,r,Min,M
MinMax(a,2,7,Min,Max)

Input : a[l r], ( l ≤ r )
Output Mi
Mô tả :
MinMa
r)
{
MinMax(a,l, (l+r) / 2, Min1, Max1);
MinMax(a,(l+r) /2 + 1, r , Min2, Max2);
in2)
Max = Max1
Else
;

: n = Min (a[l], ,a[r]),
Max = Max (a[l], ,a[r]).

x(a,l, r, Min, Max)

if (l ==
{
Min = a[l];
Max = a[l];
}
Else

If (Min1 < M

Min = Min1;
Else
Min = Min2;
If (Max1 > Max2)

Max = Max2
}
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 36 -


4. Độ phức tạp thuật toán
Gọi T(n) là số phép toán so sánh cần thực hiện. Khi đó ta có :



= 1;0 n

>+ 2;2)2( nnT

1k


+)2(nT


== 2;1)( nnT
Với n = 2
k
, thì :


+==++=+=
1
1222
2)2(2)2/(222)2/(22)(
i
ik
TnTnTnT L


=

2
2
1=i
Vậy T(n) ∈ O(n).
5. Cài đặt
3
22222
11
−=−−=−
−+
n
kkki

.
1−
k
=


void MinMax(int a[.], int l, int r, int &Min, int &Max )
ax1,Max2;
= a[l];
,(l+r)/2 , Min1, Max1);
MinMax(a,(l+r) /2 + 1,r, Min2, Max2);
if (Min1 < Min2)
Min = Min1;
if (Max1 > Max2)
x1;
x2;

. Th ật to Q
{
in2,M int Min1,M
if (l == r )
{
Min
Max= a[l];
}
else
{
MinMax(a,l




else
Min = Min2;

Max = Ma
lse e
Max = Ma
}
}
IV u án uickSort
D hu án Quiùng t ật to ckSort (QS) để sắp xếp các giá trò trong một mảng các
heo ột th tự, ch ạn tăng dần.
hương áp QuickSort (hay còn gọi là phân đoạn) là một cải tiến của
ương áp sắp xếp đổi chỗ trực tiếp, do C.A.R. Hoare đề xuất.
số t m ứ ẳng h
P ph
ph ph
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 37 -


1. Ý tưởng
Chọn ngẫu nhiên một phần tử x.
từ bên trái ( theo chỉ số i ) trong khi còn a

i
< x.
Duyệt dãy từ bên phải ( theo chỉ số j ) trong khi còn a
j
> x.
ưa vượt qua nhau.
, ,j (Dãy
m
a
h
=
ø sắp xếp bằng phân hoạch).
Duyệt dãy
Đổi chỗ a
i
và a
j
nếu hai phía ch
. . . tiếp tục qúa trình duyệt và đổi chỗ như trên trong khi hai phía còn chưa
vượt qua nhau ( tức là còn có i
≤ j).

Kết qủa phân hoạch dãy thành 3 phần : •
a
k
≤ x với k = 1 con thấp);
a
≥ x với m = i, ,n (Dãy con cao);
x với h = j+1, ,i - 1.
(Vì thế phương pháp này còn gọi la

a
k
a
m
x
Tiếp tục phân hoạch cho phần trái (dãy con thấp nhỏ hơn x), cho phần phải (
lớn hơn x) . . . cho đến khi các phân hoạch chỉ còn lại một phần tử, là sắp xếp xong.
Thuật toán thể hiện ý tưởng đệ qui và cách thiết kế chia để trò.
2. Mô tả thuật toán
- Thuật toán QuickSort
uickSort (a,n)

QS(a,1,n) ;
Mô tả :
i = l;
a[(l+r)/2]; // Chọn phần tử giữa
while (a[i] < x )
while (a[j] > x)
j ;
if (i <= j)
{
đổichỗ a[i] và a[j];
i++;
Input : a[1 n]
Output : a[1 n] không giảm.
Mô tả thuật toán :
Q
- Thuật toán phân hoạch
Input : a[1 n],l,r;
Output : a[l r] tăng dần

QS(a,l,r)

j = r;
x =
do
{

i++;


Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 38 -


j ;
}
j);
3.
}
while (i <=
if (l < j)
QS(a,l,j);
if (r > i )
QS(a,i,r);

Độ phức tạp của thuật toán
• Điều tốt nhất có thể xảy ra trong QuickSort là mỗi giai đoạn phân hoạch
phân chia mảng thành 2 nửa. Điều này khiến cho số lần so sánh cần thiết của
QuickSort thỏa mãn công thúc truy hồi “chia để trò “ sau đây :


nTT
nn
+
=
2
2 ≅ nLg n.
2
2
n
T : P
n : Ph
chia sẽ chia n phần tử thành n-1 phần tử trái và 1 phần tử phải. Kết quả
ø cần tới n phép chia ( thay cho lgn), và như thế độ phức tạp sẽ là T(n) = O(n
2
).
uật toán QuickSort
không có hiệu
• Trong trường hợp trung bình :

hí tổn sắp xếp 2 mảng con.
í tổn kiểm tra mỗi phần tử.

• Trường hợp xấu nhất ứng cho việc chọn phần tử x lại có giá trò lớn nhất
hoặc nhỏ nhất trong dãy. Giả sử phần tử lớn nhất được chọn ( phần tử x ), khi đó

mỗi bước
la
Trong trường hợp dãy nhập vào đã có thứ tự (thuận hay ngược), phần tử lớn
nhất được chọn sẽ nằm ở các biên ( phải hoặc trái), cho nên th
quả.

Công thức truy hồi để tính số lần so sánh mà QuickSort cần để hoán vò
ngẫu nhiên n phần tử là :
)(
1

)1(
1
1

≤≤
−− knk
T
; Với n ≥ 2; C
0
= C
1
= 1.
Giá trò n+1 b tử phân hoạch với mỗi phần tử
còn lại, tổng còn lại k có thể là phần tử phân hoạch
với xác suất
++=
n
n
nT +T

nk
ao hàm chi phí so sánh phần
mang ý nghóa là mỗi phần tử
1
k
và sau đó còn lại các mảng con có kích thước k-1 và n-k.



++=
kn
TnT
1
1
=

ép toán sau cho cả 2 vế : Nhân cho n và trừ cho
(n-1)C
n-1
:
n
2
k
n
1
Thực hiện liên tiếp các ph
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:


www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 39 -


∑∑
∑∑


=


=
1 kk
Ta được :


=


=

−+−−+

+−−++
−−+
1
1
11

1
1
1
1
1
1
22)1()1(
]
1
2
)[1(2)1
)1(
2
)
n
k
n
k
n
k
k
n
n
n
k
k
TTnnnn
T
n
nnT

TnT
n
n

2)1


+=−−
1
1()1(
nn
nnTnnT
=
(nn
=

1
1
k
k
=
1n
T
1
()1()1(



+
=

−−
nn
nnnnTnnT
+
Suy ra :
nTnnT
nn
2)1(
1
+
+=


Chia cả 2 vế cho n(n+1) :
−−
++=+=
21
222
nnn
TTT

∑∑
+
+=+=
1
1
2
121
nn
== 32 kk

+
++++
+
=
1
212
23
2
4
22
1
2
kk
T
nn
L

+−++
1111
nnnnnn

)ln(2
1
2
1
2 ndx
T
n
=≅≅




n
n
1
1
3
xkn
k
+
=
Như vậy, Độ phức tạp trung bình là O(nlnn)
ma trận

V. Thuật toán nhân Strassen nhân 2
1. Bài toán
Cho 2 ma trận vuông a, b cấp n, n là luỹ thừa 2.
rận vuông cấp n. Dùng thuật toán Strassen nhân 2 ma t
2. Mô tả
Ứng dụng thiết kế chia để trò, mỗi ma trận A, B, C ta chia thành 4 ma trận
ma trận con đó :











121112111211
BBAACC

ùch chia đẻ trò này dẫn đến công
là kết quả này cho lời giải T(n)
∈ θ

ma
ộng trừ vô hướng theo công thức truy hồi :
/2) + 18(n/2)
2
∈ O(n
lg7
) = O(n
2.81
).
con và biểu diễn tích 2 ma trận AxB = C theo các















=






222122212221
BBAACC
Trong đó :
C
11
= A
11
B
11
+ A
12
B
21
C
12
= A
11
B
12
+ A
12

B
22
C
21
= A
21
B
11
+ A
22
B
21
C
22
= A
21
B
12
+ A
22
B
22
Nếu theo cách nhân thông thường, thì ca
2
thưc truy hồi : T(n) = 8T(n/2) +
θ(n ). Đáng tiếc
(n
3
).
Nhưng theo khám phá của Strasen, chỉ cần 7 phép nhân đệ qui n/2 x n/2

trận và
θ(n
2
) phép c
T(n) = 7T(n
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 40 -



và 18 phép cộng (trừ) các sô. Để tính :





222122
bba
Đầu tiên tính 7 tích :
m
2
= (a
11
+ a

22
) (b
11
+ b
22
)
b
22
)
- sau đ
c
22
= m
2
– m
3
+ m
5
– m
7

if ( n == 2 )
else
;
;
12,c21,c22,n);
1,n/2);
1,n/2);
21,n/2);
strass(a21,b12,d1,n/2);

Cụ thể, để nhân 2 ma trận vuông cấp 2 , theo Strassen chỉ cần 7 phép nhân















=










1211
21
1211

2221
1211
bb
a
aa
cc
cc

-
m
1
= (a
12
- a
22
) (b
21
+ b
22
)
m
3
= (a
11
- a
21
) (b
11
+ b
12

)
m
4
= (a
11
+ a
12
) b
22

m
5
= a
11
(b
12

m
6
= a
22
(b
21
– b
11
)
m
7
= (a
21

+ a
22
) b
11

ó tính c
ij
theo công thức :
c
11
= m
1
+ m
2
– m
4
+ m
6
c
12
= m
4
+ m
5
c
21
= m
6
+ m
7



Thuật toán có thể viết như sau :
strass(a, b, c, n)


nhan2(a,b,c);

{
tach(a,a11,a12,a21,a22,n)
tach(b,b11,b12,b21,b22,n)
tach(c,c11,c

strass(a11,b11,d
strass(a12,b21,d2,n/2);
cong(d1,d2,c11,n/2);

strass(a11,b12,d1,n/2);
strass(a12,b22,d2,n/2);
cong(d1,d2,c12,n/2);

strass(a21,b11,d
strass(a22,b21,d2,n/2);
cong(d1,d2,c

Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn



Thiết kế và đánh giá thuật toán - 41 -


strass(a22,b22,d2,n/2);
cong(d1,d2,c22,n/2);
,c12,c21,c22,c,n);
I. Bài toán hoán đổi 2 phần trong 1 dãy


Hop(c11
}
V
1. Phát biểu bài toán
a[1 n] l
ảng với phần
à một mảng gồm n phần tử. Ta cần chuyển m phần tử đầu tiên của
còn lại của mảng ( n-m phân tử) mà không dùng một mảng phụ .
Chẳng ïn, v n = 8 [8] = ( 2, 3, 4 6, 7, 8
ếu m = 3, thì ết qu là : ( 4 5, 6, 7, 1, 2, 3
m
ha
k
ới

, a
,
1,
8,

, 5,
)
)
N
Nếu m = 5, thì kết quả là : ( 6, 7, 8, 1, 2, 3, 4, 5)
là : ( , 6, 7, 8, 1, 2, 3, 4) Nếu m = 4, thì kết quả 5
2. Ý tưởng
* Nếu m = n – : H ùn đổi c phần của 2 mảng ù độ da ằng n :
Nếu m
≠ n – m :
-
- Nếu m < n – m : hoán đổi m phần tử đầu với m phân tử cuối của phần còn
lại. Sau đó trong mảng a[1 n-m] ta chỉ cần hoán đổi m phần tử đầu với
phần còn lại.
- Nếu m > n – m : hoán đổi n-m phần tử đầu tiên với n-m phần tử của phần
n] ta hoán đổi n-m phần tử cuối mảng
với các phần tử của phần đầu.
Như vậy, bằng cách áp dụng phương pháp chia để trò, ta chia bài toán thành
bài to ùn con
- Bài toán thứ nhất là hoán đổi hai mảng con có độ dài bằng nhau, cụ thể là
tử đầu và cuối của mảng cho nhau bằng cách đổi chỗ
từng cặp phần tử tương ứng.
- Bài toán thứ hai cùng dạng với bài toán đã cho nhưng kích thước nhỏ hơn,
nên có thể gọi thuật toán đệ qui để giải và quá trình gọi đệ qui sẽ dừng khi
đạt tới sự hoán đổi 2 phần có độ dài bằng nhau
ậy m chốt ủa thu ïc hiện thao tác hoán đổi 2 nhóm phần tử,
ng khi số lượng phần tử của 2 nhóm cong khác nhau. Nên ta
õ thay thuật toán đệ qui bằng thuật toán lặp.
3. Thuật toán
m oa ác tử nửa co øi b hau

*
Nếu m = n – m :
sau. Sau đó trong mảng a[n-m+1 . .

2 a :
hoán đổi nửa số phần
V ấu c ật toán là thư
lặp lại thao tác này tro
se

đầu của mảng với phần còn lại.
Input : a[1 n], m. (m
Output : a[1 n] với tính chất m phần tử đầu mảng a ( mảng nhập ) nằm cuối
ảng
// Hoán đổi m phần tử
≤n)
m
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 42 -


kết quả, n-m phần tử cuối mảng nhập nằm ở đầu mảng kết
quả.
Mô tả thuật toán :

Transpose(a,n,m)

i = m; j = n-m; m = m+1;
Khi ( i
Exchange(a,m-i,m,j);
i = i – j;
Ngược lại
{
j = j – i;
Exchange(a,m-i,m+j,i);
}
ge(a,m-i,m,i);


≠ j)
Nếu ( i > j)
{

}





Exchan
* Thuật toán exchange :

input a,
i,j, //vò trí
m á ử cần ho; // So phần t án đổi

p = 0
→ m-1
n = 8, a[8] = ( 1, 2, 3, 4, 5, 6, 7, 8) , m = 3.
1 2 3 4 5 6 7 8
output a
Mô tả :
Exchange(a,i,j,m)

Với mọi
Đổichỗ (a[i+p], a[j+p]);

Minh họa :

- Mảng nhập :



Hoán đổi
- Exchange(a,1,6,3)

4 5 1 2 3 6 7 8



Hoán đổi



Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -

Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 43 -


- ange(a,1,4,2) Exch


4 5 8 6 7 1 2 3



1 2 3
Hoán đổi
- Exchange(a,3,5,1)

4 5 7 6 8


Hoán đổi
4 5 6 7 8 1 2 3
- Exchange(a,3,4,1)


- Kết thúc thuật toán.
4. Độ phức tạp thuật toán
Kí hiệu : T(i, j) là số phần tử cần đổi chỗ để hoán đổi dãy i phần tử và dãy j

àn tử, có co thức y hồi u :
>−+
=
=
i
j i nếu
j i nếu
);(
);,(
;
),(
iT
jjiTj
i
jiT

T(i,j) = i + j – UCLN(i,j)
UCLN( ước chun nhất của
5. Cài đa
pha ta âng tru sa



+
i



<−
, ji j nếu



i,j) là g lớn i, j.

ët
void Transpose(day a,int n,int m)
{
int i, j;
i = m;
j = n-m;
m = m+1;
while ( i != j )
j)
Exchan
i = i - j;
}






if(i >
{
ge(a,m-i,m,j);


Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:


www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 44 -


else
{
j = j - i;
Exchange(a,m-i,m+j,i)
}
Exchange(a,m-i,m,i);

void Exchange(day a, int i, int j, int m)
{
[j+k]);
rộn hai đường trực tiếp


;


}
//*************************
for (int k = 0; k <= m-1; k++)
doicho(a[i+k], a
}
VII. T
1. Bài toán


2.
Sắp tăng dần dãy các số bằng thuật toán trộn hai đường trực tiếp.
Ý tưởng

ước la
giai đoạn :
phần tử từ dãy F vào các dãy trung gian F1, F2
)
ộ p phần tử trong dãy F1 với p phần tử trong F2, kết quả trộn
ược đ hi chưa hết dãy F1 và chưa hết dãy F2.
òn được thực hiện trong khi p còn
≤ số các phần tử của F .
g bằng 1.
phân bố và trộn ), số phần tử p sẽ khởi động
là dãy dùng sắp thứ tự , F có nội dung như sau :
2 3 1 1
Thuật toán sắp xếp kiểu trộn hai đường trực tiếp được thực hiện theo nhiều
ëp : b
* Mỗi bước lặp bao gồm hai
Giai đoạn 1 :( Phân bố)
Phân bố luân phiên từng p
trong khi chưa hết dãy F.
Giai đoạn 2 :( Trộn
Trộn từng b
đ ưa vào F, trong k
ớc lặp c * Các bư
Bước đầu tiên p được khởi độn
ột lần Mỗi bước lặp sau( sau m
ïi là : = p * la p 2 .

Minh họa :
Giả sử F
F 9 2 1 1 5 8 1 2 9 6 7 4 6 7 2
0 1

Đầu tiên ta phân bố luân phiên từng phần tử của dãy nguồn F vào các dãy
trung gian F1 , F2.

Trong lần phân bố đầu tiên ,ta có :
F1 1 9 7 6 21 3 1 90 1 5
F2 2 1 8 2 6 4 7 2 1
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 45 -


Ta thực hiện trộn hai đường từng phần tử ở F1 với từng phần tử ởû F2; Kết
ược ghi vào F.
2-90 1-1 5-8 1-2 6-9 4-7 6-7 2-21 1-3 1
quả trộn đ

F


Sang lần thứ 2:

1 1-3 F 2-90 5-8 6-9 6-7
F2 1-1 1-2 4-7 2-21 1

F 1-1 –2-90 1-2-5-8 4-6-7-9 2-6-7-21 1-1-3


Sang lần thứ 3 :
F1 1-1 –2-90 4-6-7-9 1-1-3
F2 1-2-5-8 2-6-7-21

F 1-1-1-2-2-5-8 -90 2-4-6-6-7-7-9-21 1-1-3


Sang lần thứ 4 :
F1 1-1-1-2-2-5-8-90 1-1-3
F2 2-4-6-6-7-7-9-21

F 1-1-1-2-2-2-4-5-6-6-7-7-8-9-21-90 1-1-3

Sa

ng
1-1-1-2-2-2-4-5-6-6-7-7-8-9-21-90
lần thứ 5 :
F1
F2 1-1-3

F 1-1-1-1-1-2-2-2-3-4-5-6-6-7-7-8-9-21-90

Khi đó F được sắp thứ tự .

3. Thiết kế
* Thuật toán trộn 2 đường trực tiếp :
input F[1 n]; // dãy cần sắp
ïc sắp
ô tả:
1;
hiện :

ác dãy trung gian F1, F2
p phần tử trong dãy F1 với p phần tử trong dãy F2, kết quả
õy F1 và chưa hết dãy F2;
Output F đã đươ
M
p =
Trong khi (p <= n) ta thực
{
- Phân bố luân phiên từng p phần tử từ dãy F vào c
trong khi chưa hết dãy F.
-Trộn từng cặp
ghi vào F, trong khi chưa hết da
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 46 -



- Khởi động lại p : p = p*2;
ể viết thành hàm :
F,n,F1 F2 là n toàn cục
trên 2 thao tác :
ân phiên p phần tử từ dãy F vào các dãy trung gian
àn tử trong F1, và p phần tử trong F2, kết quả lưu
a hết dãy F1 và chưa hết dãy F2;

hiên p phần tử từ dãy F vào các dãy trung gian F1, F2 cho
án hết
Input F
Output
iện

Đọc từng p phần tử trong F và chép luân phiên vào F1, F2;
tự động việc chép luân phiên vào F1 và F2.
a thực
phần tử của F vào F1 trước.
au mo
}
Mô tả trên có th
// , các biế
void mergesort ()
{
p = 1;
while ( p <= n )
{
distribution (p);
merge(p);
p = p * 2;

}
}
Như vậy, thuật toán chủ yếu được xây dựng
- distribution (p) : Phân bố lu
F1, F2 trong khi chưa hết dãy F.
- merge(p) : Trộn từng cặp p pha
trử vào F, trong khi chư
a) Thuật toán phân bố
Phân bố luân p
dãy F. đe
a1) Thiết kế :
;
F1,F2;
Mô tả
Thực h
{

}
Trong khi ( chưa hết dãy F);

Trong mô tả trên, có 2 thao tác con cần phải lưu ý :
T ùchao ta 1 :
Làm thế nào để xử lý một cách
T hiện bằng cách : Dùng một khoá k, với k
∈ {1,2} và quy đònh :
Nếu k = 1 thì chép vào F1;
Nếu k = 2 thì chép vào F2;
Giả sử đầu tiên cho k = 1 để quyết đònh chép p
S ãi lần chép xong p phần tử, ta chỉ cần khởi động lại giá trò k = 3-k .
Thao tác 2 :

Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 47 -


Đọc p phần tử của F chép vào F1 như thế nào ? Ta đọc từng phần tử của F
và chép phần tử đó vào F1; Việc đọc chép từng phần tử này còn được thực hiện
trong khi chưa đủ p phần tử và chưa hết dãy F.
Vậy thao tác phân bố có thể mô tả chi tiết như sau :
do
{
i = 1;
while ( i <= p && chưa hết dãy F )


chép vào F1;
chép vào F2;



}
ile ( chưa hết dãy F);
Thao tác phân bố cài đặt thành một hàm như sau :
oàn cục.
t p)


, l = 1;
l <= n)
[h1] = F[l];

+;
}
{
Đọc phần tử thứ i trong F;
if ( k == 1)

else
i++;
}
k = 3-k;
wh


//F, F1, F2, n, h
1
,h
2
là các biến t
void distribute(in
{
int i, k=1
h1 = 0; h2 = 0;
do
{
i = 1;

while( i<=p &&
{
if(k==1)
{
h1++;
F1
}
else
{
h2++;
F2[h2] = F[l];
}
i++;
l+

Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -
Sưu tầm bởi:

www.daihoc.com.vn


Thiết kế và đánh giá thuật toán - 48 -





}
p phần tử trong F1 và p phần tử trong F2.

p phần tử trong F2, kết quả lưu trử vào
F, trong khi chưa hết F1 và F2.
a1) Thi
Input F1, F2;
Output
Mô tả :
Trong khi ( chưa hết dãy F1 và chưa hết dãy F2 )
{
cặp p phần tử của F1 và của F2 vào F;
dãy F1)
ử còn lại của F1 vào F;
dãy F2)
ép các phần tử còn lại của F2 vào F;
hỉ rõ công việc trộn từng cặp p phần tử của F1 và của F2 vào F
ù là :
(*) : ọc tư g F1, trong F2, so sánh giá trò của chúng, giá trò nào
ương ứng vào F. Nếu là phần tử của F1 thì đọc tiếp 1
gược lại thì đọc tiếp 1 phần tử của F2
( ** ) tác trên còn được thực hiện trong khi : chưa đọc đủ p phần tử trong F1
ø chưa đọc đủ p phần tử trong F2 và chưa hết dãy F1 và chưa hết dãy F2;
- Vòng lặp (**) dừng khi đã đọc đủ p phần tử trong F1, hoặc đã đọc đủ p phần tử
trong F2, hoặc hết dãy F1 hoặc hết dãy F2
)
k = 3-k;
}
while(l <= n);
b) Thuật toán trộn từng bộ
T øng bộ p phần tử trong F1, và rộn tư
ết kế :
F;



Trộn từng
}
Trong khi (chưa hết
chép các phần t
Trong khi (chưa hết
ch

- Ta cần c
hoạt động như thế nào ? Đo
- Đ øng phần tử tron
nhỏ hơn thì chép phần tử t
phần tử của F1; n
- :Thao
va
; Và khi đó ta cần xử lý các trường hợp
sau :
Trong trường hợp chưa hết dãy F1 và chưa hết dãy F2 :
Nếu chưa đủ p phần tử trong F1, thì đọc và chép các phần tử của F1
vào F cho đủ p; Tương tự như vậy cho F2.
a2) Cài đặt :
/* F,F1,F2,n,h
1
,h
2
là các biến toàn cục.
Ta dùng các biến :
- r
1

: đếm các phần tử đọc được trong dãy F
1
.
- r
2
: đếm các phần tư đọc được trong dãy F
2
.
- i1 : duyệt dãy F1
- i2 = 1 duyệt dãy F2
*/
void merge(int p
Trần Tuấn Minh Khoa Toán-Tin
Simpo PDF Merge and Split Unregistered Version -

×