Professional Documents
Culture Documents
Trong khoa học máy tính, sắp xếp trộn (merge sort) là một thuật toán sắp xếp để sắp xếp
các danh sách (hoặc bất kỳ cấu trúc dữ liệu nào có thể truy cập tuần tự, v.d. luồng tập tin)
theo một trật tự nào đó. Thuật toán này là một ví dụ tương đối điển hình của lối thuật toán
chia để trị. Nó được xếp vào thể loại sắp xếp so sánh.
Mục lục
[ẩn]
• 1 Trộn
• 2 Trộn tại chỗ
• 3 Trộn từ dưới lên
• 4 Sắp xếp trộn đệ quy
• 5 Trộn các đường tự nhiên
o 5.1 Khái niệm đường chạy
o 5.2 Giải thuật
o 5.3 Ưu và nhược điểm
• 6 Mã giả
o 6.1 Trộn
o 6.2 Trộn từ dưới lên
o 6.3 Trộn đệ quy
• 7 Xem thêm
[sửa] Trộn
Giả sử có hai danh sách đã được sắp xếp a[1..m] và b[1..n.]. Ta có thể trộn chúng lại thành
một danh sách mới c[1..m + n] được sắp xếp theo cách sau:
• So sánh hai phần tử đứng đầu của hai danh sách, lấy phần tử nhỏ hơn cho vào danh
sách mới. Tiếp tục như vậy cho tới khi một trong hai danh sách là rỗng.
• Khi một trong hai danh sách là rỗng ta lấy phần còn lại của danh sách kia cho vào
cuối danh sách mới.
Ví dụ: Cho hai danh sách a = (1,3,7,9),b = (2,6), quá trình hòa nhập diễn ra như sau:
Xuất phát từ đầu danh sách a ta trộn a[1] với a[2], a[3] với a[4],... Khi đó mọi danh sách
con gồm hai phần tử của a đã được sắp. Tiếp tục trộn các danh sách con kế tiếp nhau gồm
2 phần tử thành các danh sách con 4 phần tử ... Mỗi lần trộn số các danh sách con cần trộn
giảm đi một nửa. Quá trình dừng lại khi số danh sách con chỉ còn một.
Để sắp xếp trộn đoạn a[k1..k2] của danh sách a[1..n] ta chia đoạn đó thành 2 phần a[k1..k3]
và a[k3 + 1..k2],trong đó k3 = int((k1 + k2) / 2) tiến hành sắp xếp với mỗi phần rồi trộn chúng
lại. Lời gọi thủ tục sắp xếp trộn với a[1..n] sẽ cho kết quả là sắp toàn bộ danh sách a[1..n]
Giải thuật trộn đệ quy chia a thành hai danh sách con và tiến hành 3 bước
Danh sách trái Danh sách phải
2,7,6 3,4,5,1
Một đường chạy của dãy số a là một dãy con không giảm của cực đại của a. Nghĩa
là, đường chạy r = (ai, ai+1, ..., aj) phải thỏa điều kiện:
Ví dụ dãy 12, 2, 8, 5, 1, 6, 4, 15 có thể coi như gồm 5 đường chạy (12); (2, 8); (5);
(1, 6); (4, 15).
Các bước thực hiện thuật toán trộn tự nhiên như sau:
• Bước 1 : // Chuẩn bị
• Bước 2 :
Tách dãy a1, a2, ..., an thành 2 dãy b, c theo nguyên tắc luân phiên từng đường chạy:
• Bước 2.1 :
• Bước 2.2 :
• Bước 3 :
• Bước 4 :
Thuật toán trộn tự nhiên khác thuật toán trộn trực tiếp ở chỗ thay vì luôn cứng nhắc phân
hoạch theo dãy con có chiều dài k, việc phân hoạch sẽ theo đơn vị là đường chạy. ta chỉ
cần biết số đường chạy của a sau lần phân hoạch cuối cùng là có thể biết thời điểm dừng
của thuật toán vì dãy đã có thứ tự là dãy chi có một đường chạy.
Một nhược điểm lớn nữa của thuật toán trộn là khi cài đặt thuật toán đòi hỏi thêm không
gian bộ nhớ để lưu các dãy phụ b, c. Hạn chế này khó chấp nhận trong thực tế vì các dãy
cần sắp xếp thường có kích thước lớn. Vì vậy thuật toán trộn thường được dùng để sắp xếp
các cấu trúc dữ liệu khác phù hợp hơn như danh sách liên kết hoặc file.
[sửa] Mã giả
[sửa] Trộn
Procedure Merge(a,k1,k2,k3)
Var Int i,j,k
List T[k1..k3]
{
i=k1
j=k2
k=k1
while i<k2 and j<=k3
{
if a[i]<=a[j] then {
T[k]=a[i]
i=i+1
}
else {
T[k]=a[j]
j=j+1
}
k=k+1
}
if i>=k2 then
while k<=k3 {
T(k)=a[j]
j=j+1
k=k+1
}
if j>k3 then
while k<k2 {
T(k)=a[i]
i=i+1
k=k+1
}
For k=k1 to k3
a[k]=T[k]
}
Merge(a,k1,k3+1,k2)
}
}