1. Trang chủ
  2. » Luận Văn - Báo Cáo

đề tài 8 nghiên cứu và cài đặt chương trình thực hiện 6 giải thuật sắp xếp select sort insert sort bubble sort merge sort quick sort heap sort để sắp xếp dãy số theo chiều giảm dần

33 7 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

Lý thuyếtThuật toán chọn Selection Sort sắp xếp một mảng bằng cách đi tìm phần tử cógiá trị nhỏ nhất giả sử với sắp xếp mảng tăng dần trong dãy số chưa được sắp xếp vàđổi cho phần tử nhỏ

Trang 1

TRƯỜNG ĐẠI HỌC KINH TẾ QUỐC DÂN

********************************************BÀI TẬP LỚN

Môn: Cấu trúc dữ liệu và giải thuật

Đề tài 8: Nghiên cứu và cài đặt chương trình thực hiện 6 giải thuật sắp xếp (Select Sort, Insert Sort, Bubble Sort, Merge Sort, Quick Sort, Heap Sort) để sắp xếp dãy số theo chiềugiảm dần

Nhóm 1: Nguyễn Minh HiếuNguyễn Đức HuyNguyễn Huy BáchTrần Việt HoàngNguyễn Văn HảiNguyễn Trung HiếuLớp: TIHT1101(122)_01

Giảng viên: Lê Minh Tuấn

Hà Nội - 2022

Trang 2

Mục lục

I GIẢI THUẬT SẮP XẾP CHỌN (SELECTION SORT) 3

II GIẢI THUẬT SẮP XẾP CHÈN (INSERT SORT) 8

III GIẢI THUẬT SẮP XẾP NỔI BỌT (BUBBLE SORT) 13

IV GIẢI THUẬT SẮP XÉP TRỘN (MERGE SORT) 16

V GIẢI THUẬT SẮP XÉP NHANH (QUICK SORT) 23

VI GIẢI THUẬT SẮP XẾP VUN ĐỐNG (HEAP SORT) 28

Trang 3

I GIẢI THUẬT SẮP XẾP CHỌN (SELECTION SORT)

1 Lý thuyết

Thuật toán chọn (Selection Sort) sắp xếp một mảng bằng cách đi tìm phần tử cógiá trị nhỏ nhất (giả sử với sắp xếp mảng tăng dần) trong dãy số chưa được sắp xếp vàđổi cho phần tử nhỏ nhất đó với phần tử ở đầu dãy chưa được sắp xếp (không phảiđầu mảng) Thuật toán sẽ chia mảng làm 2 mảng con:

- Mảng con đã được sắp xếp- Mảng con chưa được sắp xếp

Tại mỗi bước lặp của thuật toán, phần tử nhỏ nhất ở mảng con chưa được sắp xếp sẽđược di chuyển về đoạn đã sắp xếp.

2 Ý tưởng

Giả sử cần sắp xếp giảm dần một danh sách có n phần từ a0, a1, a2, …, an-1

Chọn phần từ lớn nhất trong n phần tử của danh sách ban đầu Tìm và đổi vị trí phầntử lớn nhất với phần tử đầu tiên trong danh sách Lúc này, phần tử a0 sẽ có giá trị lớnnhất trong danh sách.

Sau đó, xem danh sách cần sắp xếp hiện tại chỉ gồm n-1 phần tử, bắt đầu từ phầntử thứ 2 trong danh sách ban đầu, tức là danh sách hiện tại chỉ gồm a1, a2, …, an-1.Lặp lại quá trình trên cho danh sách hiện tại đến khi danh sách hiện tại chỉ còn 1 phầntử.

3 Các bước thực hiện bài toán

- Bước 1: gán i = 0

- Bước 2: tìm phần tử a[max] lớn nhất trong dãy hiện hành từ a[i] đến a[n-1].- Bước 3: đổi chỗ a[max] và a[i]

- Bước 4: nếu i < n-1 thì gán i = i+1, rồi lặp lại bước 2, ngược lại -> dừng

4 Minh hoạ thuật toán

- Cho dãy số ban đầu:

Trang 4

- Thực hiện tìm số lớn nhất trong dãy và cho lên vị trí đầu tiên của dãy Đổi chỗ 56lên đầu dãy

- Thực hiện kiểm tra tiếp dãy số từ vị trí thứ 2 tới cuối dãy Số lớn nhất là 34 nêngiữ nguyên vị trí các số:

- Tiếp tục kiếm tra từ vị trí thứ 3 và thấy số lớn nhất là 23 nên vẫn giữ nguyên vị trí.

Trang 5

- Kiểm tra tiếp từ số ở vị trí thứ 4 của dãy, thấy 22 lớn hơn 12 nên đảo 22 lên vị tríthứ 4, và ta được dãy sắp xếp giảm dần hoàn chỉnh:

5 Thời gian tính toán và độ phức tạp

- Số lượng phép so sánh: (n-1) + (n-2) + (n-3) + … + 1 = n.(n-1) ~ n2- Độ phức tạp: O(n2)

- Ngoài ra, chúng ta có thể phân tích độ phức tạp bằng cách quan sát số vòng lặp có2 vòng lặp nên độ91 phức tạp là n.n = n2.

- Không gian sử dụng bộ nhớ: O(1).

6 Ưu điểm và nhược điểm của thuật toán

a Ưu điểm:

- Thuật toán đơn giản, dễ thực hiện.- Số lần đổi vị trí các số trong dãy ít.b Nhược điểm:

- Chỉ được áp dụng trong các trường hợp có số lượng phần tử cần so sánh ít.- Không nhận biết được mảng đã được sắp xếp.

7 CODE

a Hàm đổi chỗ 2 số nguyên:

Trang 6

b Hàm Selection Sort:

Trang 7

c Hàm xuất mảng:

d Hàm main:

e Kết quả:

Trang 8

8 Tổng kết

- Selection Sort không phù hợp với các dữ liệu lớn do công đoạn tìm phần tử nhỏnhất trong nhóm “lộn xộn” trông tưởng chừng đơn giản (nếu nhìn bằng mắtthường thì khá nhanh để phát hiện ra), tuy nhiên khi thực sự bắt tay vào thực hiệnthì chúng ta sẽ gặp khá nhiều khó khăn liên quan đến thời gian.

- Thứ tự sắp xếp của Selection Sort cũng được đánh giá là chưa ổn định.- Chúng ta cần vận dụng linh hoạt và khéo léo vào tùy trường hợp khác nhau.II GIẢI THUẬT SẮP XẾP CHÈN (INSERT SORT)

1 Lý thuyết giải thuật sắp xếp chèn

Sắp xếp chèn (Insert Sort) là một thuật toán sắp xếp đơn giản hoạt động tương tự

như cách bạn sắp xếp các thẻ chơi trong tay Mảng hầu như được chia thành một phần được sắp xếp và một phần chưa được sắp xếp Các giá trị từ phần chưa được sắp xếp được chọn và đặt ở vị trí chính xác trong phần được sắp xếp.

Đặc điểm của Sắp xếp Chèn: Thuật toán này là một trong những thuật toán đơn

giản nhất với cách thực hiện đơn giản

Về cơ bản, sắp xếp chèn hiệu quả đối với các giá trị dữ liệu nhỏ Sắp xếp chèn có bản chất thích ứng, tức là nó thích hợp cho các tập dữ liệu đã được sắp xếp một phần.

Thuật toán sắp xếp chèn (Insert Sort Algorithm)

Để sắp xếp một mảng có kích thước n theo thứ tự giảm dần:

Bước 1: Lặp lại từ arr [1] đến arr [n] trên mảng.

Bước 2: So sánh phần tử hiện tại với phần tử trước của nó.

Bước 3: Nếu phần tử chính lớn hơn phần tử trước của nó, hãy so sánh nó với các

phần tử trước đó Di chuyển các phần tử nhỏ hơn lên một vị trí để tạo khoảng trống cho phần tử được hoán đổi.

Ảnh minh họa thuật toán sắp xếp chèn

Trang 9

Cách hoạt động của Insert Sort

Trang 10

6 5 11 12 13

 Tại i = 2 Ta có a[2] = 11 Lúc này key = a[2] = 11, key so sánh với a[1] thấy rằng 11 lớn hơn 5 nên a[2] và a[1] đổi chỗ, tiếp tục tương tự với a[0] =6 và a[1] = 11 Vì 11 lớn hơn 6 nên a[0] và a[1] tiếp tục đổi chỗ Ta được mảng

11 6 5 12 13

 Tại i = 3 Ta có key = a[3] = 12 lớn hơn a[2], a[1], a[0] tương ứng 11, 6, 5 nên sẽ di chuyển về đầu, tức a[0] = key = 12 Chỉ số của các phần tử a[i] hiện tại sẽ thành a[i+1].

Lúc này ta có mảng a = [12, 11, 6, 5, 13]

12 11 6 5 13

 Tại i = 4 Ta có key = a[4] = 13 sẽ chuyển đến vị trí đầu tiên của mảng vì a[4] = 13 lớn hơn tất cả các giá trị trước nó, lúc này a[0] = key = 13 Các chỉ số của phần tử trong mảng tiếp tục tăng thêm 1 (a[i] = a[i+1]).

Kết thúc thuật toán, ta thu được mảng a đã sắp xếp giảm dần là a = [13, 12, 11, 6, 5].

13 12 11 6 5

Trang 11

2 Code mẫu giải thuật Insert SortMẫu test 1:

void insertionSort(int arr[], int n) {

int i, key, j;

for (i = 1; i < n; i++) {

key = arr[i]; j = i - 1;

while (j >= 0 && arr[j] < key) {

arr[j + 1] = arr[j]; j = j - 1;

}

arr[j + 1] = key; }

}

Trang 12

int main() {

int arr[] = { 12, 11, 13, 5, 6 }; int n = sizeof(arr) / sizeof(arr[0]); insertionSort(arr, n);

printArray(arr, n); return 0;

}

3 Độ phức tạp thuật toán sắp xếp chèn (Insert Sort)

Độ phức tạp về thời gian: O (n * 2)

Không gian phụ trợ: O (1)

Trường hợp ranh giới: Sắp xếp chèn mất thời gian tối đa để sắp xếp nếu các

phần tử được sắp xếp theo thứ tự ngược lại Và cần thời gian tối thiểu (Thứ tự của n) khi các phần tử đã được sắp xếp.

Mô hình thuật toán: Phương pháp tiếp cận gia giảm

Sắp xếp tại chỗ: Có

Ổn định: Có

Trực tuyến: Có

Công dụng: Sắp xếp chèn được sử dụng khi số lượng phần tử nhỏ Nó cũng có thể

hữu ích khi mảng đầu vào gần như được sắp xếp, chỉ có một số phần tử bị đặt sai vị trí trong một mảng lớn hoàn chỉnh.

III GIẢI THUẬT SẮP XẾP NỔI BỌT (BUBBLE SORT)

1 Khái niệm

 Bubble Sort là thuật toán sắp xếp đơn giản nhất hoạt động bằng cách hoán đổi nhiều lần các phần tử liền kề nếu chúng không đúng thứ tự Thuật toán này không phù hợp với các tập dữ liệu lớn vì độ phức tạp thời gian trung bình và trường hợp xấu nhất của nó là khá cao.

2 Ý tưởng

 Ý tưởng thuật toán cũng giống như việc xếp hàng trong giờ thể dục Thầy giáo thể dục muốn xếp các bạn trong lớp thành một hàng theo thứ tự từ thấp đến cao, thầy so sánh chiều cao của 22 bạn học sinh đứng cạnh nhau trong hàng, nếu bạn bên phải thấp hơn bạn bên trái thì đổi chỗ 22 bạn cho nhau.

3 Chi tiết thuật toán

 Xét một mảng gồm nn số nguyên: a_1, a_2, a_3, , a_na 1 ,a 2 ,a 3 , ,a n + Với cách sắp xếp không giảm từ trái qua phải, mục đích của chúng ta là đưadần các số lớn nhất về cuối dãy (ngoài cùng bên phải)

Trang 13

+ Bắt đầu từ vị trí số 11, xét lần lượt từng cặp 22 phần tử, nếu phần tử bên phải nhỏ hơn phần tử bên trái, ta sẽ thực hiện đổi chỗ 22 phần tử này, nếu không, xét tiếp cặp tiếp theo Với cách làm như vậy, phần tử nhỏ hơn sẽ "nổi" lên, còn phần tử lớn hơn sẽ "chìm" dần và về bên phải

+ Khi kết thúc vòng thứ nhất, ta sẽ đưa được phần tử lớn nhất về cuối dãy Sang vòng thứ hai, ta tiếp tục bắt đầu ở vị trí đầu tiên như vậy và đưa được phần tửlớn thứ hai về vị trí thứ hai ở cuối dãy

4 Thuật toán sắp xếp nổi bọt

 Chọn một mảng gồm n phần tử.

 Điền dữ liệu của mỗi phần tử trong mảng.

 So sánh 2 phần tử liền kề, phần tử nào nhỏ sẽ nổi lên trên. Tiếp tục so sánh cho tới khi dãy sắp xếp theo thứ tự giảm dần. Cho đầu ra.

5 Ví dụ minh họa thuật toán

Trang 14

Với mỗi i = 1,2, ,n-1 ta cần n-in−i phép so sánh Do đó số nhiều nhất các lần so sánh và đổi chỗ trong giải thuật là: (n-1)+(n-2)+ +2+1= Do đó tacó độ phức tạp: O(n2).

7 Ưu nhược điểm của thuật toán

Trang 15

 Hàm main:

 Đầu vào code:

 Kết quả:

Trang 16

trong các mảng gần như được sắp xếp và sửa nó chỉ với độ phức tạp tuyến tính (2n) trong đồ hoạ máy tính.

IV GIẢI THUẬT SẮP XÉP TRỘN (MERGE SORT)

1 Lý thuyết giải thuật sắp sếp trộn

Giải thuật sắp xếp trộn (Merge Sort)

 Là một giải thuật có độ phức tạp tính toán ở mức trung bình.

Giải thuật sử dụng phương pháp chia để trị (Divide and Conquer) giống với

giải thuật sắp xếp nhanh (Quick Sort).

Ý tưởng của giải thuật sắp xếp trộn (Merge Sort)

 Cho một mảng các dãy số không theo trật tự, giải thuật chia mảng cần sắp xếp thành 2 nửa.

 Tiếp tục lặp lại việc chia các nửa mảng đã chia ở trên cho đến khi không thể chia nữa (mảng giờ đang rỗng hoặc chỉ có một phần tử).

 Sau cùng, khi các nửa đã được sắp xếp, việc ‘trộn’ (kết hợp) sẽ được thực hiện.Quá trình trộn là quá trình lấy 2 mảng nhỏ hơn đã được sắp xếp và kết hợp chúng với nhau và tạo ra một mảng lớn hơn.

2 Miêu tả giải thuật sắp xếp trộn để sắp xếp mảng theo thứ tự giảm dần

Để hiểu hơn về giải thuật, lấy ví dụ với một mảng gồm 7 phần tử arr[7] = {39, 28, 40, 5, 11, 81, 13}.

Trang 17

 Bước 1: Kiểm tra nếu vị trí bên trái (chỉ số trái) nhỏ hơn vị trí bên phải (chỉ số phải) mà mình đang xét, nếu đúng, tính chỉ số phần tử giữa mảng.

m = (0 + 6) / 2 = 3

 Bước 2: Chia mảng ban đầu gồm 7 phần tử ban đầu thành 2 mảng lần lượt gồm 4 (gồm các phần tử từ vị trí đầu đến vị trí giữa của mảng cha) và 3 phần tử (gồm cácphần tử từ vị trí kế tiếp vị trí giữa đến vị trí cuối của mảng cha)

 Bước 4: Lặp lại các bước ở bước 2 với 2 mảng con ta vừa chia ở trên, ta được 4 mảng con mới

Trang 18

 Bước 5: Lặp lại bước 3 với 4 mảng con ta vừa nhận được, ta lần lượt tìm được 4 vịtrí giữa tương ứng với 4 mảng con trên.

 Bước 6: Lặp lại việc chia với các mảng trên, ta nhận được 7 mảng con

 Bước 8: So sánh các phần tử cho từng mảng con, và kết hợp chúng thành một mảng lớn hơn theo thứ tự mình mong muốn

Trang 20

o Gọi đệ quy hàm mergeSort cho nửa đầu tiên

mergesort(array, left, mid)

o Gọi đệ quy hàm mergeSort cho nửa thứ hai mergesort(array, mid+1, right)

o Gộp 2 nửa mảng đã sắp xếp ở 2 câu lệnh trên merge(array, left, mid, right)

 Bước 4: Kết thúc

4 Cài đặt chương trình cho giải thuật sắp xếp trộn (Merge Sort)

 Ngôn ngữ C++:#include <iostream>using namespace std;

// Gộp hai mảng con arr[l m] và arr[m+1 r]void merge(int arr[], int l, int m, int r)

int i, j, k;

int n1 = m - l + 1; int n2 = r - m; // Tạo các mảng tạm int L[n1], R[n2];

// Copy dữ liệu sang các mảng tạm for (i = 0; i < n1; i++)

L[i] = arr[l + i]; for (j = 0; j < n2; j++) R[j] = arr[m + 1+ j];

// Gộp hai mảng tạm vừa rồi vào mảng arr

i = 0; // Khởi tạo chỉ số bắt đầu của mảng con đầu tiên j = 0; // Khởi tạo chỉ số bắt đầu của mảng con thứ hai k = l; // IKhởi tạo chỉ số bắt đầu của mảng lưu kết quả while (i < n1 && j < n2)

{

if (L[i] >= R[j]) {

arr[k] = L[i]; i++;

}

Trang 21

else {

arr[k] = R[j]; j++;

} k++; }

// Copy các phần tử còn lại của mảng L vào arr nếu có while (i < n1)

{

arr[k] = L[i]; i++;

k++; }

// Copy các phần tử còn lại của mảng R vào arr nếu có while (j < n2)

{

arr[k] = R[j]; j++;

k++; }}

// l là chỉ số trái và r là chỉ số phải của mảng cần được sắp xếpvoid mergeSort(int arr[], int l, int r)

if (l < r) {

// Tương tự (l+r)/2, nhưng cách này tránh tràn số khi l và r lớn int m = l+(r-l)/2;

// Gọi hàm đệ quy tiếp tục chia đôi từng nửa mảng mergeSort(arr, l, m);

mergeSort(arr, m+1, r); merge(arr, l, m, r); }

// Hàm xuất mảng

Trang 22

{ int i;

for (i=0; i < size; i++) cout << A[i] << ‘ ‘; cout << endl;

int main(){

int arr[] = {39, 28, 40, 5, 11, 81, 13};

int arr_size = sizeof(arr)/sizeof(arr[0]);//Tinh do dai mang arr cout << "Mang ban dau la:\n";

printArray(arr, arr_size); mergeSort(arr, 0, arr_size - 1);

cout << "\nMang sau khi da sap xep la:\n"; printArray(arr, arr_size);

return 0;}

Kết quả:

5 Đánh giá độ phức tạp thuật toán

 Độ phức tạp thuật toán

o Trường hợp tốt: O(nlog(n))o Trung bình: O(nlog(n))o Trường hợp xấu: O(nlog(n)) Không gian bộ nhớ sử dụng: O(n)

6.Ưu điểm và nhược điểm của thuật toán

Ưu điểm: Sắp sếp nhanh hơn so với các thuật toán cơ bản (Insertion Sort,

Selection Sort, Interchage Sort), và đôi khi nhanh hơn Quick Sort trong một số trường hợp.

Nhược điểm: thuật toán khó cài đặt, không nhận dạng được mảng đã được sắp,

nhìn chung khó hơn các thuật toán khác.

Trang 23

V GIẢI THUẬT SẮP XÉP NHANH (QUICK SORT)

1 Lý thuyết giải thuật sắp xếp nhanh

Giải thuật sắp xếp nhanh (Quick Sort) là một giải thuật hiệu quả cao và dựa trên

việc chia mảng dữ liệu thành các mảng nhỏ hơn Giải thuật sắp xếp nhanh chia mảng thành hai phần bằng cách so sánh từng phần tử của mảng với một phần tử được chọn gọi là phần tử chốt (Pivot): một mảng bao gồm các phần tử nhỏ hơn hoặc bằng phần tử chốt và mảng còn lại bao gồm các phần tử lớn hơn hoặc bằng phần tử chốt.

Tiến trình này diễn ra tiếp tục cho tới khi độ dài của các mảng con đều bằng 1 Giải thuật sắp xếp nhanh tỏ ra khá hiệu quả với các tập dữ liệu lớn khi mà độ phức tạp trong trường hợp trung bình và trường hợp xấu nhất là O(nlogn) với n là số phần tử

Kỹ thuật lựa chọn phần tử chốt trong giải thuật sắp xếp nhanh (Quick Sort)

Kỹ thuật lựa chọn phần tử chốt ảnh hưởng khá nhiều đến khả năng rơi vào các vòng lặp vô hạn trong các trường hợp đặc biệt Tốt nhất là chọn phần tử chốt (Pivot) nằm ở trung

vị của danh sách Khi đó, sau log2(n) lần chia chúng ta sẽ đạt tới kích thước các mảng con bằng 1.

Dưới đây là các cách lựa chọn phần tử chốt:

 Chọn phần tử đứng đầu hoặc phần tử đứng cuối làm phần tử chốt. Chọn phần tử đứng giữa danh sách làm phần tử chốt.

 Chọn phần tử trung vị trong ba phần tử đứng đầu, đứng giữa và đứng cuối làm phần tử chốt.

 Chọn phần tử ngẫu nhiên làm phần tử chốt.

Các hoạt động của Quick Sort

Ví dụ sắp xếp dãy a=[6, 3, 5, 2, 1, 4, 8, 7] thành dãy không tăng:

Khởi tạo biến l và r là chỉ số đầu và cuối của đoạn cần sắp xếp, khởi tạo l = 0 và r = n-1;Xác định phần tử chốt trong dãy p=a[(l+r)/2] = a[3] =2.

i j ↆ ↆ

Sử dụng biến i và biến j để chia dãy thành hai phần Biến i sẽ chạy tử l đến r và biến j sẽ chạy từ r về l Nếu phát hiện a[i] <= p và a[j] >= p thì dừng lại và hoán đổi vị tri của chúng.

while (i < j){

while (a[i] > p){i++;

Ngày đăng: 14/08/2024, 16:14

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w