1. Trang chủ
  2. » Công Nghệ Thông Tin

các thuật toán sắp xếp đơn giản

13 191 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 13
Dung lượng 154,67 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

THUẬT TOÁN BUBBLE SORT • Ý tưởng của thuật toán • Ví dụ minh họa • Minh họa thuật toán sử dụng ngôn ngữ C++ • Đánh giá thuật toán 1. Ý tưởng của thuật toán bubble sort Thuật toán sắp xếp bubble sort thực hiện sắp xếp dãy số bằng cách lặp lại công việc đổi chỗ 2 số liên tiếp nhau nếu chúng đứng sai thứ tự (số sau bé hơn số trước với trường hợp sắp xếp tăng dần) cho đến khi dãy số được sắp xếp. 2. Ví dụ minh họa Giả sử chúng ta cần sắp xếp dãy số 5 1 4 2 8 này tăng dần. Lần lặp đầu tiên: ( 5 1 4 2 8 ) –> ( 1 5 4 2 8 ), Ở đây, thuật toán sẽ so sánh hai phần tử đầu tiên, và đổi chỗ cho nhau do 5 > 1. ( 1 5 4 2 8 ) –> ( 1 4 5 2 8 ), Đổi chỗ do 5 > 4 ( 1 4 5 2 8 ) –> ( 1 4 2 5 8 ), Đổi chỗ do 5 > 2 ( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ), Ở đây, hai phần tử đang xét đã đúng thứ tự (8 > 5), vậy ta không cần đổi chỗ.

Trang 1

BỘ THÔNG TIN VÀ TRUYỀN THÔNG

HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG

-BÀI TIỂU LUẬN HỌC PHẦN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

CÁC THUẬT TOÁN SẮP XẾP ĐƠN GIẢN

Nhóm: 16 Nguyễn Đình Linh- B17DCCN376 Đoàn Đức Toàn- B17DCCN607 Trần Khánh Tùng- B17DCCN667 Bùi Đăng Quang-B17DCCN502

Hà Nội, ngày 05 tháng 05 năm 2019

Mục lục

Trang 2

Insertion sort:……… 6 Selection sort:……… 9 Tài liệu tham khảo:………12

Trang 3

THUẬT TOÁN BUBBLE SORT

• Ý tưởng của thuật toán

• Ví dụ minh họa

• Minh họa thuật toán sử dụng ngôn ngữ C++

• Đánh giá thuật toán

1 Ý tưởng của thuật toán bubble sort

Thuật toán sắp xếp bubble sort thực hiện sắp xếp dãy số bằng cách lặp lại công việc đổi chỗ 2 số liên tiếp nhau nếu chúng đứng sai thứ tự (số sau bé hơn số trước với trường hợp sắp xếp tăng dần) cho đến khi dãy số được sắp xếp

2 Ví dụ minh họa

Giả sử chúng ta cần sắp xếp dãy số [5 1 4 2 8] này tăng dần

Lần lặp đầu tiên:

( 5 1 4 2 8 ) –> ( 1 5 4 2 8 ), Ở đây, thuật toán sẽ so sánh hai phần tử đầu tiên, và đổi chỗ

cho nhau do 5 > 1

( 1 5 4 2 8 ) –> ( 1 4 5 2 8 ), Đổi chỗ do 5 > 4

( 1 4 5 2 8 ) –> ( 1 4 2 5 8 ), Đổi chỗ do 5 > 2

( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ), Ở đây, hai phần tử đang xét đã đúng thứ tự (8 > 5), vậy ta

không cần đổi chỗ

Lần lặp thứ 2:

( 1 4 2 5 8 ) –> ( 1 4 2 5 8 )

( 1 4 2 5 8 ) –> ( 1 2 4 5 8 ), Đổi chỗ do 4 > 2

( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )

( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )

Bây giờ, dãy số đã được sắp xếp, Nhưng thuật toán của chúng ta không nhận ra điều đó ngay được Thuật toán sẽ cần thêm một lần lặp nữa để kết luận dãy đã sắp xếp khi và khi khi nó đi từ đầu tới cuối mà không có bất kỳ lần đổi chỗ nào được thực hiện

Lần lặp thứ 3:

( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )

( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )

( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )

( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )

Trang 4

3 Minh họa thuật toán sử dụng ngôn ngữ C++

+ Vd1:

#include<iostream>

using namespace std;

void input_func(int A[], int &n) {

cout << "nhap so phan tu cua mang

n:";

cin >> n;

for (int i = 0; i<n; i++) {

cout << "phan tu A[" << i << "]" << "=";

cin >> A[i];

}

}

// hàm sắp xếp bubblesort;

void bubblesort(int A[], int &n) {

int i = n;

bool flag = false;

while (i > 0)

{

flag = false; //khởi tạo lại giá trị cờ flag =

false;

for (int j = 0; j < i-1;j++){

if (A[j] > A[j + 1]){

int temp = A[j];

A[j] = A[j + 1];

A[j + 1] = temp;

flag = true;

}

}

if (flag == false){ //nếu không có lần đổi chỗ nào, danh sách đã sắp xếp xong

break;

} Else //nếu có ít nhất một lần đổi chỗ, danh sách chưa sắp xếp xong

{ i = i - 1;

} } } void output_func(int A[], int &n) { for (int i = 0; i < n; i++)

{ cout << A[i] << " ";

}

}

int main() { int A[100], n;

input_func(A, n);

cout << "mang ban dau la:";

output_func(A, n);

bubblesort(A, n);

cout << "mang khi sap xep la:";

output_func(A, n);

cin.get();

getchar();

return 0;

}

Nhập : 64 90 25 34 22 12 11

Xuất : 11 12 22 25 34 64 90

+ Vd2:

#include<iostream>

using namespace std;

int main() {

Trang 5

int a[50],n,i,j,temp;

cout<<"so luong: ";

cin>>n;

cout<<"nhap tung so: ";

for(i=0;i<n;++i)

cin>>a[i];

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

for(j=0;j<(n-i);++j)

if(a[j]>a[j+1]) {

temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;

} }

cout<<"ket qua bubble sort:"; for(i=0;i<n;++i)

cout<<" "<<a[i];

return 0;

}

+ Kết quả :

+ nhập : 5

8 5 6 7 2

+ xuất : 2 5 6 7 8

4 Đánh giá thuật toán sắp xếp bubble sort:

• Số phép so sánh không phụ thuộc vào tình trạng ban đầu của dãy Có thể ước lượng số phép so sánh bằng: (n-1) + (n-2) + + 1 = n(n – 1)/2.

• Số phép hoán vị (3 phép gán) phụ thuộc tình trạng ban đầu Trong trường hợp tốt nhất, tức dãy đã được sắp xếp hoàn toàn thì không cần phải hoán vị, nên số phép hoán vị là: 0.

• Trường hợp xấu nhất, tức dãy có thứ tự ngược với yêu cầu Mỗi lần so sánh ta lại phải hoán vị nên số phép hoán vị là: n(n - 1)/2.

Độ phức tạp 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)

Trang 6

THUẬT TOÁN INSERTION SORT

• Ý tưởng của thuật toán

• Ví dụ minh họa

• Minh họa thuật toán sử dụng ngôn ngữ C++

• Đánh giá thuật toán

1 Ý tưởng của thuật toán Insertion Sort

Thuật toán insertion sort thực hiện sắp xếp dãy số theo cách duyệt từng phần tử và chèn từng phần tử đó vào đúng vị trí trong mảng con(dãy số

từ đầu đến phần tử phía trước nó) đã sắp xếp sao cho dãy số trong mảng sắp đã xếp đó vẫn đảm bảo tính chất của một dãy số tăng dần.

 Khởi tạo mảng với dãy con đã sắp xếp có k = 1 phần tử(phần tử đầu tiên, phần tử có chỉ số 0)

 Duyệt từng phần tử từ phần tử thứ 2, tại mỗi lần duyệt phần tử ở chỉ số i thì đặt phần tử đó vào một vị trí nào đó trong đoạn từ [0…i] sao cho dãy số từ [0…i] vẫn đảm bảo tính chất dãy số tăng dần Sau mỗi lần duyệt, số phần tử đã được sắp xếp k trong mảng tăng thêm 1 phần tử

 Lặp cho tới khi duyệt hết tất cả các phần tử của mảng

1 Ví dụ minh họa

Trang 7

Hàng đầu tiên mô phỏng trạng thái ban đầu của mảng(dãy số chưa sắp xếp) Từ hàng thứ 2 trở đi, ta tìm chèn số đang xét vào vị trí thích hợp để đảm bảo dãy số vẫn tăng dần Và khi lặp hết tất cả các số trong mảng, ta có trạng thái

đã sắp xếp ở hàng cuối cùng

2 Minh họa thuật toán sử dụng ngôn ngữ C++

• VD:

void InsertionSort(int a[] , int n)

{

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

{

Int x = a[ i ];

Int j = i;

While( j > 0 && a[ j – 1] > x )

{

a[ j ] = a[ j -1 ] ;

j ;

}

a[ j ] = x;

}

}

3 Đánh giá thuật toán

• Trong trường hợp tốt nhất thuật toán sữ dụng n-1 phép so sánh và 0 lần hoán vị.

Trang 8

• Trung bình thuật toán sử dụng n2/4 phép so sánh và n2/4 lần hoán vị.

• Trong trường hợp xấu nhất thuật toán sử dụng n2/2 phép so sánh và n2/2 lần hoán vị.

• Thuật toán thích hợp đối với mảng đã được sắp xếp một phần hoặc mảng có kích thước nhỏ.

Độ phức tạp 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)

Trang 9

THUẬT TOÁN SELECTION SORT

• Ý tưởng của thuật toán

• Ví dụ minh họa

• Minh họa thuật toán sử dụng ngôn ngữ C++

• Đánh giá thuật toán

1 Ý tưởng của thuật toán selection sort

Thuật toán thực hiện sắp xếp dãy các đối tượng bằng cách lặp kiểu chọn Thuật toán thực hiện sắp xếp dãy các đối tượng bằng cách lặp lại việc tìm kiếm phần tử có giá trị nhỏ nhất

từ thành phần chưa được sắp xếp trong mảng và đặt nó vào vị trí đầu tiên của dãy Trên dãy các đối tượng ban đầu, thuật toán luôn duy trì hai dãy con:

Dãy con đã được sắp xếp: là các phần tử bên trái của dãy

Dãy con chưa được sắp xếp là các phần tử bên phải của dãy Quá trình lặp sẽ kết thúc khi dãy con chưa được sắp xếp chỉ còn lại đúng một phần tử

Các bước thực hiện của thuật toán selection sort

Bước 1: Thiết lập MIN về vị trí 0

Bước 2: Tìm kiếm phần tử nhỏ nhất trong danh sách

Bước 3: Tráo đổi với giá trị tại vị trí MIN

Bước 4: Tăng MIN để trỏ tới phần tử tiếp theo

Bước 5: Lặp lại cho tới khi toàn bộ danh sách đã được sắp xếp

2 Ví dụ minh họa

Giả sử chúng ta cần sắp xếp dãy số [5 1 4 2 8] này tăng dần

Từ vị trí đầu tiên trong danh sách đã được sắp xếp, toàn bộ danh sách được duyệt một cách liên tục Vị trí đầu tiên có giá trị 5, chúng ta tìm toàn bộ danh sách và thấy rằng 1

là giá trị nhỏ nhất

Lần lặp đầu tiên:

( 5 1 4 2 8 ) –> ( 1 5 4 2 8 ), Do đó, chúng ta thay thế 5 với 1 Sau một vòng lặp, giá trị 1

thay thế cho giá trị 5 tại vị trí đầu tiên trong danh sách đã được sắp xếp Chúng ta tráo đổi hai giá trị này

Lần lặp thứ 2:

( 1 5 4 2 8 ) –> ( 1 2 4 5 8 ), Tại vị trí thứ hai, giá trị 5, chúng ta tiếp tục quét phần còn lại

của danh sách theo thứ tự từng phần tử Chúng ta thấy rằng 2 là giá trị nhỏ nhất thứ hai trong danh sách và nó nên xuất hiện ở vị trí thứ hai Chúng ta tráo đổi hai giá trị này Sau hai vòng lặp, hai giá trị nhỏ nhất đã được đặt tại phần đầu của danh sách đã được sắp xếp

Tiến trình tương tự sẽ được áp dụng cho phần còn lại của danh sách Phía dưới minh họa cho các tiến trình này

Lần lặp thứ 3:

( 1 2 4 5 8) –> ( 1 2 4 5 8), Ở đây, hai phần tử đang xét đã đúng thứ tự, vậy ta không cần đổi chỗ

Trang 10

Lần lặp thứ 4:

( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ), Ở đây, hai phần tử đang xét đã đúng thứ tự, vậy ta không cần đổi chỗ

3 Minh họa thuật toán sử dụng ngôn ngữ C++

+ Vd1:

#include<iostream>

using namespace std;

void swap(int &xp, int &yp)

{

int temp = xp;

xp = yp;

yp = temp;

}

// Hàm selection sort

void selectionSort(int arr[], int &n)

{

int i, j, min_idx;

// Di chuyen ranh gioi cua mang dã

sap xep và chua sap xep

for (i = 0; i < n-1; i++)

{

// Tìm phan tu nho nhat trong mang

chua sap xep

min_idx = i;

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

if (arr[j] < arr[min_idx])

min_idx = j;

// Ðoi cho phan tu nho nhat voi phan

tu dau tiên

swap(arr[min_idx], arr[i]);

}

}

/* Hàm xuat mang */

void printArray(int arr[], int &size)

{ int i;

for (i=0; i < size; i++) printf("%d ", arr[i]);

printf("\n");

}

/* Hàm nhap mang */

void inputArray(int arr[], int &size) {

cout << "nhap so phan tu cua mang n:";

cin >> size;

for (int i = 0; i<size; i++) {

cout << "phan tu A[" << i

<< "]" << "=";

cin >> arr[i];

} }

int main() {

int arr[100];

int n;

inputArray(arr,n);

selectionSort(arr, n);

printf("Sorted array: \n");

printArray(arr, n);

return 0;

}

+ Kiểm tra kết quả:

Trang 11

Nhập : 64 90 25 34 22 12 11

Xuất : 11 12 22 25 34 64 90

Trang 12

4 Đánh giá thuật toán sắp xếp selection sort :

Để chọn được phần tử nhỏ nhất, ta cần duyệt qua n phần tử (tốn n-1 phép so sánh) và sau đó hoán vị nó với phần tử đầu tiên của dãy hiện hành Để tìm phần tử nhỏ nhất tiếp theo, ta cần duyệt qua n-1 phần tử (tốn n-2 phép so sánh) Cứ như vậy, ta thấy ngay thuật toán sẽ tốn (n-1) + (n-2) + … + 1 = n(n-1)/2 = O(n2) phép so sánh.

Mỗi lần duyệt, ta luôn phải hoán vị 1 lần (1 hoán vị tương đương với 3 phép gán), nghĩa là thuật toán sẽ tốn 3(n-1) + 3(n-2) + … + 3 = 3n(n-1)/2 = O(n2) phép gán.

Tổng kết lại, ta luôn có độ phức tạp của thuật toán Selection Sort là O(n2) trong mọi trường hợp.

Độ phức tạp 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)

Tài liệu tham khảo

Trang 13

• https://en.wikipedia.org/wiki/Selection_algorithm

Ngày đăng: 29/08/2019, 12:07

TỪ KHÓA LIÊN QUAN

w