You are on page 1of 6

Trường ĐH KHTN – ĐHQG TP.

HCM Thực hành CTDL&GT – Lớp 18CTT2A

BÁO CÁO
(V/v tìm hiểu các thuật toán sắp xếp tăng dần)

1. Người báo cáo


1.1. Họ và tên: Nguyễn Bảo Long
1.2. MSSV: 18120201
1.3. Lớp: 18CTT2A
2. Nội dung chi tiết các thuật toán
2.1. Thuật toán Selection Sort
2.1.1. Ý tưởng: Chọn phần tử nhỏ nhất trong N phần tử ban đầu, sau đó đưa
phần tử này lên đầu dãy đang xét và không quan tâm đến nó nữa. Lặp lại
thao tác này đối với dãy 𝑁 − 1 phần tử còn lại cho đến khi mảng không còn
phần tử nào để sắp xếp nữa.
2.1.2. Thuật toán
2.1.2.1. Bước 1: 𝑖 = 1
2.1.2.2. Bước 2: Tìm phần tử a[min] nhỏ nhất trong dãy hiện hành từ 𝑎[𝑖]
đến 𝑎[𝑁]
2.1.2.3. Bước 3: Hoán vị 𝑎[𝑚𝑖𝑛] và 𝑎[𝑖]
2.1.2.4. Bước 4: Nếu 𝑖 < 𝑁 − 1 thì 𝑖 = 𝑖 + 1. Quay lại bước 2. Nếu
không thì dừng thuật toán.
2.1.3. Đánh giá thuật toán:
Trường hợp Số lần so sánh Số phép gán
Tốt nhất 𝑛(𝑛 − 1) 0
2
Xấu nhất 𝑛(𝑛 − 1) 3𝑛(𝑛 − 1)
2 2
Từ bảng trên, ta thấy, độ phức tạp của Selection Sort là 𝑂(𝑛4 )
2.2. Thuật toán Insertion Sort
2.2.1. Ý tưởng: Tìm cách chèn phần tử 𝑎5 vào dãy 𝑎6 , 𝑎4 , … , 𝑎596 đã có thứ tự
sao cho nó ở đúng vị trí, tạo thành 1 dãy mới có thứ tự.
2.2.2. Thuật toán:
2.2.2.1. Bước 1: 𝑖 = 2
2.2.2.2. Bước 2: 𝑥 = 𝑎[𝑖]. Tìm vị trí pos thích hợp trong đoạn 𝑎[1] đến
𝑎[𝑖 − 1] để chèn 𝑎[𝑖] vào.
2.2.2.3. Bước 3: Dời chỗ các phần tử từ a[pos] đến 𝑎[𝑖 – 1] sang 1 đơn vị
để lấy chỗ cho 𝑎[𝑖]
2.2.2.4. Bước 4: 𝑎[𝑝𝑜𝑠] = 𝑥
2.2.2.5. Bước 5: 𝑖 = 𝑖 + 1. Nếu 𝑖 ≤ 𝑛: Lặp lại bước 2, ngược lại: Dừng
thuật toán.
Trường ĐH KHTN – ĐHQG TP.HCM Thực hành CTDL&GT – Lớp 18CTT2A

2.2.3. Đánh giá thuật toán


Trường hợp Số lần so sánh Số phép gán
Tốt nhất 𝑛−1 2(𝑛 − 1)
Xấu nhất 𝑛(𝑛 − 1) 𝑛(𝑛 + 1)
−1
2 2
Từ bảng trên, ta thấy, độ phức tạp của Insertion Sort là 𝑂(𝑛4 )
2.3. Thuật toán Interchange Sort
2.3.1. Ý tưởng:
- Nghịch thế: Trong một mảng 𝑎@ , 𝑎6 , 𝑎4 , … , 𝑎A , nếu tồn tại 𝑖 < 𝑗 và
𝑎5 > 𝑎D thì 𝑎5 và 𝑎D được gọi là một nghịch thế
- Ý tưởng: Tìm tất cả các nghịch thế trong mảng và triệt tiêu chúng bằng
cách đổi chỗ chúng cho đến khi trong mảng không còn tồn tại nghịch
thế.
2.3.2. Thuật toán:
2.3.2.1. Bước 1: 𝑖 = 1
2.3.2.2. Bước 2: 𝑗 = 𝑖 + 1
2.3.2.3. Bước 3: Trong khi 𝑗 ≤ 𝑁, thực hiện:
- Nếu 𝑎[𝑗] < 𝑎 [𝑖 ]: 𝑎[𝑖 ] đổi chỗ cho 𝑎[𝑗]
- 𝑗 = 𝑗 + 1
2.3.2.4. Bước 4: 𝑖 = 𝑖 + 1
- Nếu 𝑖 < 𝑛: Lặp lại bước 2
- Ngược lại: dừng thuật toán.
2.3.3. Đánh giá thuật toán:
Trường hợp Số lần so sánh Số lần hoán vị
Tốt nhất 𝑛 (𝑛 − 1 ) 0
2
Xấu nhất 𝑛(𝑛 − 1) 𝑛(𝑛 − 1)
2 2
Từ bảng trên, ta thấy, độ phức tạp của Interchange Sort là 𝑂(𝑛4 )
2.4. Thuật toán Bubble Sort
2.4.1. Ý tưởng: Xuất phát từ cuối (đầu) dãy, đổi chỗ các phần tử kế cận để đưa
phần tử nhỏ (lớn) hơn lên đầu (cuối) dãy hiện hành, sau đó sẽ không xét
đến nó ở vị trí tiếp theo. Do vậy ở lần xử lý thứ 𝑖 sẽ có vị trí đầu dãy là 𝑖.
Thuật toán dừng lại khi không còn phần tử nào để xét.
2.4.2. Thuật toán:
2.4.2.1. Bước 1: 𝑖 = 1
2.4.2.2. 𝑗 = 𝑁
- Trong khi (𝑗 < 𝑖), thực hiện:
o Nếu 𝑎[𝑗] < 𝑎 [𝑗 − 1]: Đổi chỗ 𝑎[𝑗], 𝑎[𝑗 − 1]
o 𝑗 = 𝑗 − 1
2.4.2.3. 𝑖 = 𝑖 + 1
- Nếu 𝑖 > 𝑁 − 1: Hết dãy. Dừng thuật toán.
- Ngược lại: Lặp lại bước 2
Trường ĐH KHTN – ĐHQG TP.HCM Thực hành CTDL&GT – Lớp 18CTT2A

2.4.3. Đánh giá thuật toán:


Trường hợp Số lần so sánh Số lần hoán vị
Tốt nhất (
𝑛 𝑛−1 ) 0
2
Xấu nhất 𝑛(𝑛 − 1) 𝑛(𝑛 − 1)
2 2
4
Từ bảng trên, ta thấy, độ phức tạp của Bubble Sort là 𝑂(𝑛 )
2.5. Thuật toán Shaker Sort
2.5.1. Ý tưởng: Dựa trên nguyên tắc đổi chỗ trực tiếp, nhưng tìm cách khắc phục
những nhược điểm của Bubble Sort với những ý tưởng cải tiến chính như
sau:
- Trong mỗi lần sắp xếp, duyệt mảng theo 2 lượt từ 2 phía khác nhau:
o Lượt đi: Đẩy phần tử nhỏ về đầu mảng
o Lượt về: Đẩy phần tử lớn về cuối mảng
- Ghi nhận lại những đoạn đã sắp xếp nhằm tiết kiệm các phép so sánh
thừa.
2.5.2. Thuật toán:
2.5.2.1. Bước 1: 𝑙 = 1, 𝑟 = 𝑛, 𝑘 = 𝑛
2.5.2.2. Bước 2:
- Bước 2a: 𝑗 = 𝑟
Trong khi (𝑗 > 𝑙)
Nếu 𝑎[𝑗] < 𝑎 [𝑗 − 1]: Đổi chỗ 𝑎 [𝑗], 𝑎[𝑗 − 1]; 𝑘 = 𝑗
𝑗 =𝑗−1
𝑙=𝑘
- Bước 2b: 𝑗 = 𝑙
Trong khi (𝑗 < 𝑟):
Nếu 𝑎[𝑗] > 𝑎 [𝑗 − 1]: Đổi chỗ 𝑎 [𝑗], 𝑎[𝑗 − 1]; 𝑘 = 𝑗
𝑗 =𝑗+1
𝑟=𝑘
2.5.2.3. Bước 3: Nếu 𝑙 < 𝑟. Lặp lại bước 2.
2.5.3. Đánh giá thuật toán:
Trường hợp Độ phức tạp
Tốt nhất 𝑂(𝑛)
Trung bình 𝑂(𝑛4 )
Xấu nhất 𝑂(𝑛4 )

2.6. Thuật toán Merge Sort


2.6.1. Ý tưởng: Chia mảng ra thành các dãy con nhỏ. Sắp xếp các dãy con đó rồi
gộp chúng lại với nhau tạo thành một mảng có thứ tự
2.6.2. Thuật toán:
2.6.2.1. Bước 1: Tách dãy số thành các dãy con chỉ có 2 hoặc 1 phần tử.
2.6.2.2. Bước 2: Sắp xếp các dãy con vừa được tách.
2.6.2.3. Bước 3: Gộp chung các dãy con lại thành 1 dãy có thứ tự.
Trường ĐH KHTN – ĐHQG TP.HCM Thực hành CTDL&GT – Lớp 18CTT2A

2.6.2.4. Bước 4: Kiểm tra nếu đã xét hết dãy mẹ thì dừng thuật toán. Ngược
lại, quay trở lại bước 2.
2.6.3. Đánh giá thuật toán: Ta thấy ở bước 2 và 3, số lần lặp của thuật toán là
log 4 𝑛 và chi phí của 2 bước này tỷ lệ với 𝑛. Như vậy, chi phí thực hiện Merge
Sort là 𝑂(𝑛 log 4 𝑛).
2.7. Thuật toán Quick Sort
2.7.1. Ý tưởng: Chia mảng cần sắp xếp thành 3 phần:
- Phần 1: Mảng con chứa các phần tử nhỏ hơn x
- Phần 2: Phần tử x, là 1 phần tử được chọn ra từ mảng ban đầu
- Phần 3: Mảng con chứa các phần tử lớn hơn x
Lặp lại sự phân chia này với hai phần 1 và 3 cho đến khi các mảng con
chỉ còn 1 phần tử duy nhất thì dừng thuật toán.
2.7.2. Thuật toán:
2.7.2.1. Bước 1: Chọn tuỳ ý một phần tử 𝑎[𝑘] trong dãy làm giá trị mốc.
𝑙≤𝑘≤𝑟
𝑥 = 𝑎 [𝑘 ], 𝑖 = 𝑙, 𝑗 = 𝑟
2.7.2.2. Bước 2: Phát hiện và hiệu chỉnh các cặp phần tử 𝑎[𝑖], 𝑎[𝑗] nằm sai
chỗ:
- Bước 2a: Trong khi (𝑎[𝑖] < 𝑥) 𝑖++
- Bước 2b: Trong khi (𝑎 [𝑗] > 𝑥) 𝑗—
- Bước 2c: Nếu 𝑖 < 𝑗: Hoán vị 𝑎[𝑖 ] và 𝑎[𝑗]
2.7.2.3. Bước 3:
- Nếu 𝑖 < 𝑗: Lặp lại bước 2
- Nếu 𝑖 ≥ 𝑗: Dừng thuật toán
2.7.3. Đánh giá thuật toán
Trường hợp Độ phức tạp
Tốt nhất 𝑛𝑙𝑜𝑔(𝑛)
Trung bình 𝑛𝑙𝑜𝑔(𝑛)
Xấu nhất 𝑛4

2.8. Thuật toán Flash Sort


2.8.1. Ý tưởng
2.8.2. Thuật toán
2.8.3. Đánh giá độ thuật toán
2.9. Thuật toán Radix Sort
2.9.1. Ý tưởng: Cho dãy ban đầu 𝑎6 , 𝑎4 , … , 𝑎A .
- Trước tiên, ta giả sử mỗi phần tử 𝑎5 trong dãy là một số nguyên dương
có m chữ số.
- Ta phân loại các phần tử lần lượt theo các chữ số hàng đơn vị, chục,
trăm,…
2.9.2. Thuật toán
2.9.2.1. Bước 1: // 𝑘 cho biết chữ số dùng để phân loại hiện hành
- 𝑘 = 0 // 𝑘 = 0: hàng đơn vị, 𝑘 = 1: hàng chục, …
Trường ĐH KHTN – ĐHQG TP.HCM Thực hành CTDL&GT – Lớp 18CTT2A

2.9.2.2. Bước 2: Tạo các lô chứa các loại phần tử khác nhau. Khởi tạo 10 lô:
𝐵@ , 𝐵6 , 𝐵4 , … , 𝐵P rỗng.
2.9.2.3. Bước 3: Đặt 𝑎5 vào lô 𝐵D với 𝑗 là chữ số thứ 𝑘 của 𝑎5
2.9.2.4. Bước 4: 𝑘 = 𝑘 + 1. Nếu 𝑘 < 𝑚 thì trở lại bước 2. Ngược lại: Dừng
thuật toán.
2.9.3. Đánh giá độ thuật toán: Độ phức tạp của thuật toán là 𝑂(𝑛) và chỉ sắp
xếp được các mảng số nguyên dương.
2.10. Thuật toán Heap Sort
2.10.1.Ý tưởng: Xây dựng cây MinHeap từ các phần tử ban đầu của mảng. Cây
MinHeap thoả mãn một tính chất quan trọng là phần tử root của cây luôn
là phần tử nhỏ nhất. Ta tiến hành lấy phần tử đầu tiên của cây MinHeap ra,
đưa vào mảng kết quả và hiệu chỉnh lại cây sao cho nó vẫn là cây MinHeap.
2.10.2.Thuật toán
2.10.2.1. Giai đoạn 1: Hiệu chỉnh dãy số ban đầu thành Heap
2.10.2.2. Giai đoạn 2:
- Bước 1: Đưa phần tử lớn nhất về vị trí đúng ở cuối dãy: 𝑟 = 𝑛, Hoán vị
𝑎6 và 𝑎Q
- Bước 2: Loại bỏ phần tử lớn nhất ra khỏi Heap: 𝑟 = 𝑟 − 1. Hiệu chỉnh
các phần tử còn lại của dãy từ 𝑎6 , 𝑎4 , … , 𝑎Q thành 1 heap
- Bước 3: Nếu 𝑟 > 𝑙: Lặp lại bước 2. Ngược lại: Dừng.
2.10.3.Đánh giá thuật toán: Việc đánh giá Heap Sort rất phức tạp nhưng người
ta đã chứng minh được trong trường hợp xấu nhất, độ phức tạp của thuật
toán xấp xỉ bằng 𝑂(𝑛 log 4 𝑛)
2.11. Thuật toán Counting Sort
2.11.1.Ý tưởng: Áp dụng với mảng chứa các phần tử nguyên không âm, hoặc một
danh sách ký tự được ánh xạ về dạng số thập phân. Counting Sort đếm số
lần xuất hiện của các giá trị khác nhau trong mảng ban đầu và gán giá trị
vừa đếm vào vị trí tương ứng của 1 mảng có độ dài là giá trị lớn nhất của
mảng.
2.11.2.Thuật toán:
2.11.2.1. Bước 1: Tìm 𝑀𝑎𝑥 = max(𝑎𝑟𝑟𝑎𝑦[ ])
2.11.2.2. Bước 2: Tạo mảng động ∗ 𝑆𝑜𝐿𝑢𝑜𝑛𝑔 có độ dài là 𝑀𝑎𝑥 và
𝑆𝑜𝐿𝑢𝑜𝑛𝑔[𝑖] = 0, 𝑖𝑛𝑡 ∗ 𝑆𝑜𝐿𝑢𝑜𝑛𝑔 = 𝑛𝑒𝑤 (𝑖𝑛𝑡 ∗)𝑐𝑎𝑙𝑙𝑜𝑐(𝑀𝑎𝑥, 𝑠𝑖𝑧𝑒𝑜𝑓(𝑖𝑛𝑡))
2.11.2.3. Bước 3: Đếm số lần xuất hiện của các giá trị khác nhau trong mảng
ban đầu. Và gán giá trị vào vị trí tương ứng ở mảng 𝑆𝑜𝐿𝑢𝑜𝑛𝑔
2.11.2.4. Bước 4: Sắp xếp lại mảng ban đầu bằng cách duyệt mảng 𝑆𝑜𝐿𝑢𝑜𝑛𝑔
2.11.3.Đánh giá thuật toán:
Trường hợp Độ phức tạp
Tốt nhất 𝑂(𝑛)
Xấu nhất 𝑂(𝑛)
Trung bình 𝑂(𝑛)
Trường ĐH KHTN – ĐHQG TP.HCM Thực hành CTDL&GT – Lớp 18CTT2A

2.12. Binary Insertion Sort


2.12.1.Ý tưởng: Kế thừa ý tưởng của thuật toán Insertion Sort, Binary Insertion
Sort sử dụng thuật toán Binary Search để tìm ra vị trí thích hợp cho việc
chèn phần tử.
2.12.2.Thuật toán:
2.12.2.1. Bước 1: 𝑖 = 2
2.12.2.2. Bước 2: 𝑥 = 𝑎[𝑖]. Tìm vị trí pos thích hợp trong đoạn 𝑎[1] đến
𝑎[𝑖 − 1] để chèn 𝑎[𝑖] vào bằng cách sử dụng thuật toán Binary Search
2.12.2.3. Bước 3: Dời chỗ các phần tử từ a[pos] đến 𝑎[𝑖 – 1] sang 1 đơn vị
để lấy chỗ cho 𝑎[𝑖]
2.12.2.4. Bước 4: 𝑎[𝑝𝑜𝑠] = 𝑥
2.12.2.5. Bước 5: 𝑖 = 𝑖 + 1. Nếu 𝑖 ≤ 𝑛: Lặp lại bước 2, ngược lại: Dừng
thuật toán.
2.12.3.Đánh giá thuật toán: Độ phức tạp giống như thuật toán Insertion Sort
3. Tổng kết
- Các thuật toán đã được cài đặt thử trên cấu hình máy
o CPU: Intel Core i5, xung nhịp 2.7GHz
o Ram: 16GB 1867 MHz DDR3
- Các bộ dữ liệu dùng để test bao gồm
o Kích cỡ: Mảng số nguyên 1000 phần tử, 3000 phần tử, 10.000
phần tử, 30.000 phần tử, 100.000 phần tử
o Kiểu dữ liệu đầu vào: Ngẫu nhiên, Đã sắp xếp, Sắp xếp ngược, Bán
sắp xếp.
- Kết quả về thời gian chạy được tổng hợp trong biểu đồ sau
Thời gian chạy của các thuật toán và bộ dữ liệu tương ứng
40
35
30
25
20
15
10
5
0
Re rse_ 00

ar e_ 00
So d_3 0
d_ 00
Ra om 00

Ra m_ 00

Ne ly S d_1 0
rte 00

Re rse_ 0

Re se_1 0

00
rte 00

te 00
0
Ra om 000

_1 00

So d_3 0
d_ 00
rte 00

ar ort 00

ar rte 00
00

0
rte 00

00

0
00

Ne vers 300
rte 00
nd 10

So 000

00
30
So _10

Ne So 000
om 00

ar ort 00
rte 00
So _10
nd _ 3

Ne ly S d_1

Ne So d_3
Re se_1
So d_3

Re 100
0

10
Ra m_

1
nd _ 3

1
d

e
o

e
ve

ve
o
nd

r
r
ve

ve
nd
Ra

ly

ly
ar

ly

Bubble Sort Selection Sort Insertion Sort


Interchange Sort Quick Sort Merge Sort
Shell Sort Heap Sort Radix Sort
Binary Insertion Sort Shaker Sort Counting Sort

You might also like