Nghiên cứu về các thuật toán SortKí hiệu tổng sau ta sẽ sử dụng kí hiệu này xuyên suốt các chứng minh thời gian cho trường hợp tệ nhất a Selection Sort Ý tưởng: Từ tập dữ liệu ban đầu ta
Trang 1TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN
KHOA: TOÁN - TIN
BÁO CÁO ĐỒ ÁN CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
TÊN ĐỀ TÀI: Search + Sort
LỚP: 21KDLB
MSSV - HỌ VÀ TÊN: 21280109 – Phan Huy Thịnh, 21280105 – Hoàng Phúc
NĂM HỌC: 2021 - 2022
GIẢNG VIÊN: Nguyễn Bảo Long
TP.HCM, ngày 24 tháng 10 năm 2022
Trang 2MỤC LỤC
PHẦN PHÂN CÔNG 1
PHẦN NỘI DUNG 1
I.Ý TƯỞNG CHUNG 1
II.NGHIÊN CỨU VỀ CÁC THUẬT TOÁN SORT 1
a) Selection sort 1
b) Insertion sort 2
c) Bubble sort 4
d) Interchange sort 4
e) Quick sort 5
f) Merge sort 6
g) Heap sort 7
III.NGHIÊN CỨU VỀ CÁC THUẬT TOÁN SEARCH .8
a) Linear search 8
b) Binary search 8
BIỂU ĐỒ SO SÁNH VÀ NHẬN XÉT VỀ THỜI GIAN CHẠY CỦA CÁC THUẬT TOÁN .10
MỨC ĐỘ HOÀN THÀNH VÀ TỰ ĐÁNH GIÁ 12
Trang 3PHẦN PHÂN CÔNG
Trình bày ý tưởng, đưa ra chứng minh cho trường hợp tệ nhất, đo thời gian chạy của các thuật toán Sort, nhận xét biểu đồ thời gian chạy,
hoàn tất báo cáo
Trình bày mã giả, cài đặt các thuật toán, (cùng thực hiện) đo thời gian chạy của các thuật toán Sort, vẽ biểu đồ thời gian chạy, làm khung báo
cáo
PHẦN NỘI DUNG
I Ý tưởng chung
Nghiên cứu tất cả các thuật toán Search và Sort, đưa ra mã giả sau đó lập trình, rồi so sánh thời gian chạy của các thuật toán Sort Từ đó nhận xét các thuật toán Search và đưa ra các trường hợp thuận lợi, trung bình và phức tạp nhất của thuật toán Sort
II Nghiên cứu về các thuật toán Sort
Kí hiệu tổng sau ta sẽ sử dụng kí hiệu này xuyên suốt các chứng minh thời gian cho trường hợp tệ nhất
a) Selection Sort
Ý tưởng: Từ tập dữ liệu ban đầu ta tìm được phần tử nhỏ nhất, đưa phần tử nhỏ nhất
ra vị trí đầu tiên Sau đó tìm phần tử nhỏ nhất trong tập dữ liệu còn lại rồi đưa vào vị trí thứ hai Quá trình lặp đi lặp lại cho đến khi không còn phần tử nào thì chúng ta có được dữ liệu cần sắp xếp
Mã giả:
Thuật toán Selection Sort(A, n)
Input: Mảng A có n phần tử
Output: Mảng A xếp theo thứ tự tăng dần
for (i 0 to n – 2) do
Trang 4k i;
for (j i + 1 to n – 1) do
if ( A[k] > A[j] ) then k j;
A[k] A[i];
Output A;
Độ phức tạp ở cả 3 trường hợp đều là ,
Chứng minh (tất cả các dòng đều được thực hiện):
for (i 0 to n – 2) do
k i;
for (j i + 1 to n – 1) do
if ( A[k] > A[j] ); vì có 2 thao tác định vị và 1 thao tác so sánh
k j;
A[k] A[i];
Tổng lại:
b) Insertion Sort
Ý tưởng: Tìm vị trí thích hợp trong mảng sau đó chuyển dữ liệu và vị trí thích hợp trống và đưa dữ liệu mới vào Bài toán tìm vị trí sẽ dùng phương pháp tìm kiếm tuần tự để giải quyết và duyệt tuần tự ở cuối mảng
Mã giả:
Thuật toán Insertion Sort(A, n)
Input: Mảng A có n phần tử
Output: Mảng A xếp theo thứ tự tăng dần
for j = 2 to n do
x A[j];
i j – 1;
while i > 0 and A[i] > x do
A[i+1] A[i]
i i-1;
A[i + 1] x;
Trang 5Độ phức tạp:
Chứng minh cho trường hợp tệ nhất: 1
for j = 2 to n do
x A[j];
i j – 1;
while i > 0 and A[i] > x do
A[i+1] A[i]
i i-1;
A[i + 1] x;
Tổng lại:
c) Bubble Sort
Ý tưởng: Nếu cứ hai phần tử nghịch thế thì chúng ta sẽ đổi chỗ để không còn nghịch thế, hay nói cách khác các phần tử nhỏ hơn sẽ "trồi lên trên" Các phần tử lớn hơn sẽ
"chìm xuống dưới"
Mã giả:
Thuật toán Bubble Sort(A, n)
Input: Mảng A có n phần tử
Output: Mảng A xếp theo thứ tự tăng dần (nhẹ nổi lên)
for (i 0 to n – 2) do
for (j n – 1 to i + 1) do
if (A[j –1] > A[j]) then A[j –1] A[j]
Output A;
Độ phức tạp:
Chứng minh cho trường hợp tệ nhất:
1 Thomas H Cormen Charles E Leiserson Ronald L Rivest Clifford Stein Introduction to Algorithms Third
Trang 6Dòng Độ phức tạp
for (i 0 to n – 2) do
for (j n – 1 to i + 1) do
if ( A[j – 1 ] > A[j] )
A[k] A[i];
Tổng lại:
d) Interchange Sort
Ý tưởng: Tìm các cặp nghịch thế và hoán vị chúng để giảm nghịch thế, xuất phát
từ phần tử đầu tiên của dãy
Mã giả:
Thuật toán Interchange Sort(A, n)
Input: Mảng A có n phần tử
Output: Mảng A được sắp xếp tăng dần
for (i 0 to n – 2) do
for (j i + 1 to n – 1) do
if (A[i] > A[j]) then A[i] A[j];
output A;
Độ phức tạp:
Chứng minh cho trường hợp tệ nhất:
for (i 0 to n – 2) do
for (j i + 1 to n – 1 ) do
if ( A[i ] > A[j] )
A[i] A[i];
Tổng lại:
e) Quick Sort
Trang 7Ý tưởng: Lấy 1 phần tử ở giữa mảng (gọi phần tử đó là X) sau đó chia ra làm 2
dữ liệu (bên trái X và bên phải X) Nếu phần tử nhỏ hơn X thì sắp xếp bên trái, còn lớn hơn
X thì sắp xếp bên phải
Mã giả:
Thuật toán Quick Sort(A, left, right)
Input: Mảng A có các phần tử từ left đến right
Output: Mảng A xếp theo thứ tự từ left đến right
Chọn phần tử X;
i left; j right;
while (i < j) do
while(A[i] < X) do i i + 1;
while(A[j] > X) do j j – 1;
if (i < j) then
A[i] A[j];
i i + 1;
j j –1;
if (j > left) then Quick Sort(A, left, j);
if (i < right) then Quick Sort(A, i + 1, right);
Output A;
Độ phức tạp:
Ta chứng minh độ phức tạp bằng các hệ thức dệ quy dựa trên ý tưởng: từ mảng n, thông qua thao tác Partition (phân chia) để đưa phần tử X đã chọn đến 1 vị trí mà trước vị trí đó là mảng có n phần tử, sau vị trí đó là mảng n phần tử:1 2
Trường hợp tệ nhất là mảng đã được sắp xếp rồi:
f) Merge Sort
Trang 8Ý tưởng: Mảng A nếu ta chia thành hai phần bằng nhau, nếu ta sắp xếp hai phần
rồi trộn hai nửa lại ta có được thứ tự toàn phần
Mã giả:
Thuật toán Merge Sort (A, left, right)
Input: Mảng A có các phần tử ở vị trí từ left đến right
Output: Mảng A xếp theo thứ tự từ left đến right
if (left < right) then
mid (left + right) / 2
Merge Sort(A, left, mid);
Merge Sort(A, mid + 1, right)
Trộn A[left, mid] và A[mid + 1, right] thành A[left, right]
Output A;
Độ phức tạp như nhau trong cả 3 trường hợp và bằng
Ta chứng minh dựa trên hệ thức đệ quy sau:
(i là số lần cưa đôi mảng)
Sẽ đến lúc tức
Từ đó
g) Heap Sort
Ý tưởng: Ta thấy rằng trong selection sort, cứ mỗi vòng lặp ta phải tìm phần tử nhỏ nhất trong số các phần tử còn lại Trong quá trình tìm kiếm ta không tận dụng được các thông tin của lần trước đó Một cách tiếp cận khác là ta sẽ làm sao lưu trữ thông tin các lần tìm kiếm trước đó để có thể sử dụng sau này
Mã giả:
Thuật toán Heap Sort(A, n)
Input: Mảng A có n phần tử
Trang 9Output: Mảng A được sắp xếp tăng dần
Create Heap(A, n); // Mảng A là heap max
for (i n – 1 to 1) do
A[0] A[k];
Insert Heap (A, 0, i – 1); //Mảng A chứa heap
Output A;
Độ phức tạp ở 3 trường hợp đều như nhau và bằng
Thật vậy, Ở thao tác tạo Heap từ mảng A mất thời gian là có (n-1) lần chèn Heap vào mà ở mỗi lần chèn Heap mất thời gian là (điều này tương tự với thao tác Partition phân chia ở thuật toán MergeSort, nó mất lần cưa đôi mảng), tóm lại :
III Nghiên cứu các thuật toán Search
a) Linear Search
Ý tưởng: Duyệt phần tử đầu tiên cho đến phần tử cuối cùng để tìm phần tử thỏa điều kiện cần tìm
Mã giả:
Thuật toán Linear Search (A, n, key)
Input: Mảng A có n phần tử và điều kiện key
Output: Vị trí phần tử cần tìm, hoặc –1 nếu không tìm thấy
for (i 0 to n – 1) do
if (A[i] thỏa mãn điều kiện key) output i;
else output –1;
Nhận xét: Thuật toán có thể áp dụng trên mọi tiêu chuẩn tìm kiếm cũng như mọi dữ liệu Tuy nhiên chi phí cao (tỉ lệ với )
b) Binary Search
Ý tưởng: Phân hoạch làm 2 phần, 1 phần chắc chắn không có, phần còn lại nếu
có sẽ tồn tại Quá trình tìm kiếm không gian sẽ bị thu hẹp, nên việc tìm kiếm sẽ nhanh chóng Điều kiện phần tử phải có quan hệ thứ tự nào đó
Mã giả:
Trang 10Thuật toán Binary Search (A, n, key)
Input: Mảng A có n phần tử và điều kiện key
Output: Vị trí phần tử cần tìm, hoặc –1 nếu không tìm thấy
left 0; right n 1;
while (left right) do
mid (left + right) / 2;
if (A[mid] thỏa key) then output mid;
if (A[mid] thỏa key ở bên trái) then right mid 1;
if (A[mid] thỏa key ở bên phải) then left mid + 1;
Không thỏa while thì output 1;
Nhận xét: Thuật toán có chi phí thấp (tỉ lệ ) Tuy nhiên, thuật toán không tổng quát, không thể áp dụng trên mọi tiêu chuẩn tìm kiếm cũng như mọi dữ liệu Dữ liệu bắt buộc phải có quan hệ thứ tự toàn phần và việc tìm kiếm dữ liệu phải theo quan hệ thứ tự này
BIỂU ĐỒ SO SÁNH THỜI GIAN CHẠY
Trang 11Ở đây, ta có 3 biểu đồ, ứng với các tình trạng dữ liệu: ngẫu nhiên (Random), sắp xếp tăng (Sorted), giảm dần (Reversed)
Hình 1 Biểu đồ cho dữ liệu ngẫu nhiên
Nhận xét: Với lượng dữ liệu nhỏ đến vừa (1000 đến 10000) các thuật toán không tỏ ra quá
khác biệt trong tốc độ xử lí, nhưng khi dữ liệu tăng mạnh thì dễ thấy các thuật toán đơn giản như Bubble, Interchange kém hiệu quả, Heap Sort xử lí tốt nhất
Trang 12Hình 2 Biểu đồ cho dữ liệu sắp xếp tăng
Nhận xét: Ngoại trừ Merge, Heap hay Selection sort gần như không khác biệt Khi kích
thước dữ liệu tăng mạnh thì đã có sự chênh lệch: cụ thể mảng sắp xếp tăng khiến cho Quick Sort rơi vào trường hợp tệ nhất nhưng vẫn mạnh hơn Bubble và Selection sort, Bubble sort tuy đã rơi vào trường hợp tốt nhất nhưng tốc độ vẫn chậm càng chứng tỏ đây là thuật toán kém hiệu quả
Trang 13Hình 2 Biểu đồ cho dữ liệu sắp xếp giảm
Nhận xét: Sắp xếp giảm khiến cho Bubble, Interchange mất rất nhiều thời gian xử lí, Heap
và Merge ở cả 3 trường hợp đều cho thấy sự ổn định hơn Quick sort, chứng tỏ cấu trúc cây là một cấu trúc hiệu quả khi làm việc với dữ liệu mảng
Trang 14MỨC ĐỘ HOÀN THÀNH VÀ TỰ ĐÁNH GIÁ
Chứng minh độ phức tạp hoàn chỉnh, tuy nhiên trình bày ý tưởng các thuật toán chưa thực sự cụ thể, đánh giá hoàn thành 80%
Trình bày mã giả, cài đặt các thuật toán, (cùng thực hiện) đo thời gian chạy của các thuật toán Sort, vẽ biểu đồ thời gian chạy, làm khung báo
cáo