You are on page 1of 22

Họ và tên: Trương Quốc Vương

MSSV: 19120728
Lớp: 19CTT4C

BÁO CÁO CÁC THUẬT TOÁN SẮP XẾP

I. Các thuật toán sắp xếp


1. Selection Sort
 Ý tưởng: chọn phần tử nhỏ nhất đưa về vị trí đầu tiên của mảng
hiện tại và không cần quan tâm đến nó nữa. Khi đó mảng chỉ còn lại
n - 1 phần tử của mảng ban đầu, tiếp tục xét từ phần tử thứ 2 của
mảng.
 Thuật toán:
 Tìm phần tử nhỏ nhất đưa vào vị trí 1
 Tìm phần tử nhỏ tiếp theo đưa vào vị trí 2
 Tìm phần tử nhỏ tiếp theo đưa vào vị trí 3
 ...
 VD:

 Đánh giá thuật toán:


 Trường hợp tốt: O(n^2)
 Trung bình: O(n^2)
 Trường hợp xấu: O(n^2)
 Không gian bộ nhớ sử dụng: O(1)
2. Merge Sort
 Ý tưởng: Merge sort là một thuật toán chia để trị. Thuật toán này
chia mảng cần sắp xếp thành 2 nửa. Tiếp tục lặp lại việc này ở các
nửa mảng đã chia. Sau cùng gộp các nửa đó thành mảng đã sắp
xếp.
 Thuật toán: mergeSort(arr[], left, right)
 If left < right
 Tìm chỉ số nằm giữa mảng để chia mảng thành 2 nửa:
middle mid = (left + right) / 2
 Gọi đệ quy hàm mergeSort cho nửa đầu tiên: (2)
mergeSort(arr, left, mid)
 Gọi đệ quy hàm mergeSort cho nửa thứ hai: (3)
mergeSort(arr, mid + 1, right)
 Gộp 2 nửa mảng đã sắp xếp ở (2) và (3):
merge(arr, left, mid, right)
 VD:

 Đánh giá thuật toán:


 Trường hợp tốt: O(nlog(n))
 Trung bình: O(nlog(n))
 Trường hợp xấu: O(nlog(n))
 Không gian bộ nhớ sử dụng: O(n)
3. Heap Sort
 Ý tưởng: để tìm phần tử nhỏ nhất ở bước i, phương pháp sắp xếp
chọn trực tiếp đã không tận dụng được các thông tin đã có được do
các phép so sánh ở bước i-1. Phương pháp Heap Sort khắc phục
được nhược điểm này.
 Thuật toán:
 Với một tập danh sách n phần từ T1 – T2 – T3… Tn. Ta coi
nó như một cây nhị phân.
 Quy định cho cây nhị phân như nhau. Nếu một node là tại vị
trí = i. Thì node này có 2 nhánh trái và phải tương ứng như
sau.
 Nhánh trái là phần tử 2*i + 1 và nhánh phải là 2*i+
2 với điều kiện là < n

 Nguyên lý được thực hiện như sau:


 Xây dựng đống sao cho với mọi nút cha đều có giá
trị lớn hơn nút con => nút gốc đầu tiên sẽ có giá trị
lớn nhất.
 Hoán vị nút gốc với nút thứ n-1 và xây dựng lại đống
mới với n-2, sau đó tiếp tục hoán vị nút gốc với nút
cuối của cây mới sau n-2.
 VD:
 Đánh giá thuật toán:
 Trường hợp tốt: O (nlogn) (các khóa riêng biệt) hoặc O(n)
(các khóa bằng nhau)
 Trung bình: O(nlogn)
 Trường hợp xấu: O(nlogn)
 Trường hợp phức tạp nhất về không gian: O(1)
4. QuickSort
 Ý tưởng: Quick sort là một thuật toán chia để trị nó chọn một phần tử
trong mảng để làm điểm đánh dấu. Thuật toán sẽ thực hiện chia mảng
thành các mảng con theo điểm mà mình đã chọn. Có nhiều cách chọn
điểm khác nhau:
 Luôn chọn phần tử đầu tiên
 Luôn chọn phần tử cuối cùng
 Chọn phần tử ngẫu nhiên
 Chọn phần tử ở giữa
 Thuật toán:
 Chọn phần tử chính giữa để so sánh, gọi là phần tử mid
(Pivot), từ trong mảng đầu tiên.
 Phân vùng và sort mảng con trong phân vùng làm sao cho
các phần tử lớn hơn từ phần tử mid nằm sau (bên phải) và
các phần tử bé hơn phần tử mid nằm trước (bên trái). Đây
được gọi là quá trình phân vùng.
 Cuối cùng là đệ quy sử dụng các bước trên cho các mảng
với phần tử bé hơn và phân tách với các phần tử lớn hơn
sau khi phân vùng.
 VD:
 Đánh giá thuật toán:
 Trường hợp tốt: O(nlog(n))
 Trung bình: O(nlog(n))
 Trường hợp xấu: O(n^2)
 Không gian bộ nhớ sử dụng: O(log(n))
5. Bubble Sort
 Ý tưởng: đẩy phần tử lớn nhất xuống cuối dãy, đồng thời những
phần tử có giá trị nhỏ hơn sẽ dịch chuyển dần về đầu dãy. Những
phần tử nhẹ hơn sẽ nổi lên trên và ngược lại, những phần tử lớn
hơn sẽ chìm xuống dưới.
 Thuật toán: duyệt mảng từ phần tử đầu tiên. So sánh mỗi phần tử
với phần tử liền trước nó, nếu chúng đứng sai vị trí, đổi chỗ chúng
cho nhau. Quá trình này sẽ được dừng nếu gặp lần duyệt từ đầu
dãy đến cuối dãy mà không phải thực hiện đổi chỗ bất kì 2 phần từ
nào (tức là tất cả các phần tử đã được sắp xếp đúng vị trí).
 VD:

 Đánh giá thuật toán:


 Trường hợp tốt: O(n)
 Trung bình: O(n^2)
 Trường hợp xấu: O(n^2)
 Không gian bộ nhớ sử dụng: O(1)
6. Insertion Sort
 Ý tưởng: Insertion Sort lấy ý tưởng từ việc chơi bài, dựa theo cách
người chơi "chèn" thêm một quân bài mới vào bộ bài đã được sắp
xếp trên tay.
 Thuật toán:
 Tại bước k = 1, 2, ..., n đưa phần tử thứ k trong mảng đã cho
vào đúng vị trí trong dãy gồm k phần tử đầu tiên.
 Kết quả là sau bước thứ k, sẽ có k phần tử đầu tiên được sắp
xếp theo thứ tự.

 VD:
 Đánh giá thuật toán:
 Trường hợp tốt: O(n)
 Trung bình: O(n^2)
 Trường hợp xấu: O(n^2)
 Không gian bộ nhớ sử dụng: O(1)
7. Binary-Insertion Sort
 Ý tưởng: Binary Insertion Sort cũng tương tự như Insertion Sort, chỉ
khác ở cách tìm vị trí thích hợp pos trong đoạn a[0] đến a[i-1]. Do
đoạn a[0] đến a[i-1] đã có thứ tự nên ta có thể sử dụng giải thuật tìm
nhị phân (Binary Search) để thực hiện việc tìm vị trí pos.
 Thuật toán:
 Bước 1: i = 2 // Giả sử có đoạn a[1] đã được sắp
 Bước 2: x = a[i]; Tìm vị trí pos thích hợp trong đoạn a[1] đến
a[i-1] để chèn a[i] vào.
 Bước 3: Dời chỗ các phần tử từ a[pos] đến a[i-1] sang phải 1
vị trí để dành chỗ cho a[i].
 Bước 4: a[pos] = x; // có đoạn a[1]…a[i] đã được sắp
 Bước 5: i = i +1;
 Nếu i ≤ n: lặp lại bước 2.
 Ngược lại: Dừng
 VD:
 Đánh giá thuật toán:
 Trung bình: O(n^2)
 Xấu nhất: O(n^2)
 Tốt nhất: O(n)
 Bộ nhớ: O(n)

II. Kết quả thực nghiệm


 Note: kết quả chạy chương trình được xuất ra file result.txt
1. Sắp xếp ngẫu nhiên

Randomized Input
140000

120000
Runtime in milliseconds

100000 Selection
Merge
80000
Heap
60000
QuickSort

40000 Bubble
Insertion
20000
Binary-Insertion
0
3000 10000 30000 100000 300000
Input Size

Ngẫu nhiên

 Nhận xét:
 Cùng chia sẻ vị trí đầu bảng lần lượt là Quicksort, Heapsort và
Mergesort
 Chót bảng là 2 người anh em nổi tiếng Bubblesort và Selectionsort
(trong đó Bubble chạy chậm nhất)
2. Gần như có thứ tự tăng dần

Nearly Sorted Input


35000

30000
Runtime in milliseconds

25000 Selection
Merge
20000
Heap
15000
QuickSort

10000 Bubble
Insertion
5000
Binary-Insertion
0
3000 10000 30000 100000 300000
Input Size

Gần tăng dần

 Nhận xét:
 Cùng đứng đầu bảng (thời gian chênh lệch không đáng kể) lần lượt
là Insertion, Quicksort, Binary-Insertion, Heapsort và Mergesort
(trong đó Insertion chạy nhanh nhất)
 Chót bảng lần lượt là Selection và Bubble (Bubble chạy chậm nhất)
 Insertion chạy cực nhanh trong trường hợp mảng được sắp xếp 1
phần
3. Có thứ tự tăng dần

Sorted Input
30000

25000
Runtime in milliseconds

Selection
20000
Merge
15000 Heap
QuickSort
10000
Bubble
Insertion
5000
Binary-Insertion
0
3000 10000 30000 100000 300000
Input Size

Tăng dần

 Nhận xét:
 Gần tương tự như trường hợp mảng được sắp xếp 1 phần, đứng
đầu bảng (thời gian chênh lệch không đáng kể) tiếp tục lần lượt là
Insertion, Quicksort, Binary-Insertion, Heapsort và Mergesort (trong
đó Insertion chạy nhanh nhất)
 Chót bảng vẫn lần lượt là Selection và Bubble (Bubble chạy chậm
nhất)
 Insertion tiếp tục cho thấy tốc độ chạy cực nhanh trong trường hợp
mảng được sắp xếp tăng dần
4. Thứ tự ngược (giảm dần)

Reverse Input
80000

70000
Runtime in milliseconds

60000
Selection
50000 Merge
40000 Heap
QuickSort
30000
Bubble
20000
Insertion
10000 Binary-Insertion
0
3000 10000 30000 100000 300000
Input Size

Giảm dần

 Nhận xét:
 Quicksort, Heapsort và Merge cùng đứng đầu bảng cho thấy tốc độ
chạy vượt trội của mình so với các thuật toán khác
 Bubble tiếp tục chạy chậm nhất
 Insertion đứng gần áp chót bảng, khi mảng không còn được xếp
tăng dần thì Insertion chạy tương đối chậm
 Nhận xét chung:
 Với số lượng phần từ 3000, 10000 và 30000 thì thời gian chạy của các
thuật toán không có nhiều sự khác biệt (vì quá nhỏ), bắt đầu có sự chênh
lệch nhẹ khi nâng số lượng phần tử lên 100000 và chênh lệch rõ ràng khi
lên tới 300000 phần tử
 Với số lượng phần tử từ 30000 trở xuống thì thời gian chạy của các thuật
toán là không đáng kể nên cần lựa chọn thuật toán đơn giản nhất, tránh
các thuật toán chiếm không gian, phức tạp và dễ gặp lỗi
 Nhìn chung thì Quicksort, Heapsort và Mergesort chạy nhanh trong tất cả
các trường hợp, Insertion và Binary-Insertion chạy cực nhanh khi mảng
được sắp xếp 1 phần hoặc toàn bộ, còn Bubblesort, Selectionsort chạy rất
chậm khi số lượng phần tử lớn
 Các thuật toán hiệu suất cao: Heapsort, Mergesort, Quicksort
 Các thuật toán hiệu suất thấp: Bubblesort, Selectionsort
 Các thuật toán có code phức tạp: Heapsort, Mergesort, Quicksort, Binary-
Insertion
 Các thuật toán có code đơn giản: Selectionsort, Bubblesort, Insertionsort

You might also like