1. Trang chủ
  2. » Giáo án - Bài giảng

Phân tích các thuật toán

35 394 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 35
Dung lượng 713 KB

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

Nội dung

Nó làm việc bằng cách đầu tiên tìm phần tử nhỏ nhất trong tập dữ liệu bằngcách tìm kiếm tuyến tính và hoán đổi vị trí phần tử đó với phần tử đầu tiên trong tập dữ liệu, sau đó tìm phần t

Trang 1

KHOA CÔNG NGHỆ THÔNG TIN

MÔN PHÂN TÍCH VÀ THIẾT KẾ THUẬT GIẢI

………

Đề tài: Phân tích các thuật toán Sort

Giảng viên hướng dẫn

Trang 2

MỞ ĐẦU

Đề tài nhóm chúng tôi là đánh giá độ phức tạp của các giải thuật sắp xếp Nóiđến các giải thuật sắp xếp thì có lẽ đây là một chủ đề đã quá quen thuộc và kinhđiển Tuy nhiên, vì chúng ta xem nó quá quen thuộc nên chúng ta thường hayquên nó đi Mục tiêu của đề tài này là để chúng ta cùng nhau nắm lại tư tưởng củacác thuật toán sắp xếp, độ phức tạp về mặt lý thuyết, và hơn nữa, bằng thựcnghiệm đánh giá, kiểm chứng lại các độ phức tạp này

Nội dung của phần báo cáo được chia làm 2 phần lớn:

 Nền tảng lý thuyết: Giới thiệu tổng quan về tư tưởng, độ phức tạp của cácthuật toán sắp xếp

 Thực nghiệm: Nêu lên cách tiến hành thực nghiệm, kết quả và nhận xét

Trang 3

MỤC LỤC

MỞ ĐẦU 2

MỤC LỤC 3

1.1 SELECTION SORT 4

1.1.1/ Giới thiệu sơ lược thuật toán: 4

1.2 INTERCHANGE SORT 8

1.2.1/ Giới thiệu sơ lược thuật toán: 8

1.3 BUBBLE SORT 11

1.3.2/ Thuật toán bằng mã giả: 12

1.3.3/ Mã nguồn bằng ngôn ngữ C: 12

1.3.4/ Đánh giá thuật toán: 13

1.4 INSERTION SORT 15

1.5.1/ Giới thiệu sơ lược thuật toán: 15

* Ví dụ: Cho danh sách 15

1.5.2/ Thuật toán bằng mã giả: 16

1.5.3/ Mã nguồn: 16

1.5 HEAP SORT 19

1.5.1/ Giới thiệu sơ lược thuật toán 19

1.6 MERGE SORT 23

Trong khoa học máy tính, sắp xếp trộn (merge sort) là một thuật toán sắp xếp để sắp xếp các danh sách (hoặc bất kỳ cấu trúc dữ liệu nào có thể truy cập tuần tự, v.d luồng tập tin) theo một trật tự nào đó Thuật toán này là một ví dụ tương đối điển hình của lối thuật toán chia để trị Nó được xếp vào thể loại sắp xếp so sánh 23

1.6.2/ Thuật toán bằng mã giả: 24

1.6.4/ Đánh giá thuật toán: 26

1.7 QUICK SORT 27

1.7.1/ Giới thiệu sơ lược thuật toán 27

1.8 SHELL SORT 31

1.8.1/ Giới thiệu sơ lược thuật toán 31

1.8.2/ Thuật toán bằng mã giả: 32

1.8.4/ Đánh giá thuật toán: 34

Trang 4

1.1 SELECTION SORT

1.1.1/ Giới thiệu sơ lược thuật toán:

Selection sort là một thuật toán sắp xếp khá đơn giản nhằm cải tiến tốc độ chobubble sort

Nó làm việc bằng cách đầu tiên tìm phần tử nhỏ nhất trong tập dữ liệu bằngcách tìm kiếm tuyến tính và hoán đổi vị trí phần tử đó với phần tử đầu tiên trong tập

dữ liệu, sau đó tìm phần tử nhỏ nhất thứ hai bằng cách duyệt trong phạm vi các phần

tử còn lại trừ phần tử đầu đã xếp xong, và cứ như thế Selection sort là thuật toán duynhất xét về thời gian chạy so với các thuật toán khác không bị ảnh hưởng bởi tìnhtrạng thứ tự của dữ liệu đầu vào, nó luôn thực hiện cùng số lượng các thao tác docấu trúc đơn giản của mình

Ta chọn phần tử nhỏ nhất trong N phần tử ban đầu, đưa phần tử này về đầu dãy hiện hành Sau đó, ta không quan tâm đến nó nữa, ta xem dãy hiện hành chỉ còn N-1 phần tử của dãy ban đầu tính từ vị trí thứ 2 Cứ vậy, cho đến khi dãy hiện hành chỉ còn 1 phần tử, ta được 1 dãy sắp tăng.

* Các bước tiến hành như sau:

o Bước 1: Khởi động i = 1

o Bước 2: Tìm phần tử nhỏ nhất a[min] trong dãy hiện hành từ a[i] đến a[N]

o Bước 3: Hoán vị a[min] và a[i]

o Bước 4: i = i+1

 Nếu i < =N-1: quay trở lại bước 2

 Ngược lại: STOP!

Trang 5

Void SelectionSort(int a[], int n)

//thuat toan Selection Sort

void SelectionSort(int A[],int n)

{

int min; // chi so phan tu nho nhat trong day hien hanh for(int i=0; i<n-1; i++)

Trang 6

Kết quả hiển thị với đầu vào là 1 List các số nguyên :

1.1.4/ Đánh giá thuật toán:

void SelectionSort(int A[],int n)

{

int min; // chi so phan tu nho nhat trong day hien hanh

Trang 7

- Các lệnh (2) và (5) có thời gian chạy là O(1)

- Ta đánh giá thời gian chạy của lệnh lặp (3) Số lần lặp là (n-1-i), thời gianthực hiện lệnh (4) là O(1), do đó thời gian chạy của lệnh (3) là (n-1-i)O(1)

- Như vậy, thân của lệnh lặp (1) có thời gian chạy ở lần lặp thứ i là i)O(1)

(n-1-Do đó lệnh lặp (1) đòi hỏi thời gian (n-1-i)O(1) = O(1)(1 + 2 + …+ n-1)

= O(1)n(n-1)/2 = O(n2)

Vậy thời gian chạy của hàm sắp xếp lựa chọn là O(n2)

1.1.5/ Ước lượng độ phức tập thuật toán

Để 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(n 2 ) 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(n 2 ) 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 thuộc O(n 2 ) trong mọi trường hợp.

Trang 8

1.2 INTERCHANGE SORT

1.2.1/ Giới thiệu sơ lược thuật toán:

Ý tưởng chính của thuật toán này là ta tìm các cặp nghịch thế và triệt tiêu chúng Ta xuất phát từ phần tử đầu tiên của dãy, tìm tất các các cặp nghịch thế chứa phần tử này, triệt tiêu chúng bằng các hoán vị phần tử này với phần tử tương ứng trong cặp nghịch thế Ta dễ nhận thấy sau lần duyệt đầu tiên, phần tử đầu tiên chính là phần tử nhỏ nhất của dãy

Ta tiếp tục xử lý với phần tử thứ hai, ta có được phần tử thứ hai chính là phần tử nhỏ thứ hai của dãy Cứ như vậy, sau khi xử lý với phần tử thứ N -1 của dãy, ta được một dãy sắp tăng.

* Các bước tiến hành như sau:

o Bước 1: Khởi động i = 1

o Bước 2: j = i+1

o Bước 3: Trong khi j <= N thực hiện:

 Nếu a[i]>a[j]: Hoán vị a[i] và a[j]

 j = j+1

o Bước 4: i = i+1

 Nếu i <= N-1: quay trở lại bước 2

 Ngược lại: STOP!

* Ví dụ: Mảng : 5 4 1 2 3

Vòng lặp i=0 :Xét a[0]=5Vòng lặp bắt đầu từ vị trí j=1

5>4 => a[0]=4Đến j=2

4>1 => a[0]=1Đến j=3

1 < 2 => Ko thay thay thếĐến j=4

1 < 3 => Ko thay thếGiá trị mảng sau khi kết thúc I = 0 : 1 4 2 3 5

1.2.2/ Thuật toán bằng mã giả:

void InterchangeSort ( int a[], int n)

{

int i, j;

Trang 9

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

cout<<"Nhap bao nhieu phan tu: ";cin>>n;

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

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

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

Trang 10

1.2.4/ Đánh giá thuật toán:

Số lượng các phép so sánh xảy ra không phụ thuộc vào tình trạng của dãy sốban đầu

Số lượng phép hoán vị thực hiện tùy thuộc vào kết quả so sánh

Thấy ngay số phép so sánh là luôn không đổi, tức không phụ thuộc vào tìnhtrạng ban đầu của dãy Ta có thể ước lượng số phép so sánh bằng (n-1) + (n-2) + … +

1 = n(n-1)/2 (phần tử thứ i được so sánh với n-i phần tử còn lại.)

Số phép hoán vị (tương đương 3 phép gán) lại phụ thuộc vào tình trạng banđầu của dãy Cụ thể như sau:

+ Trường hợp tốt nhất: Dãy ban đầu đã có thứ tự Ta thấy ngay ta không tốnmột phép hoán vị nào

+ Trường hợp xấu nhất: Dãy ban đầu có thứ tự ngược Ta thấy ngay mỗi lần sosánh phần tử thứ i với n-i phần tử còn lại, ta đều phải thực hiện hoán vị Điều này cónghĩa là số phép hoán vị bằng n(n-1)/2

1.2.5/ Ước lượng độ phức tạp thuật toán:

Trường hợp tốt nhất: Dãy ban đầu đã có thứ tự Ta thấy ngay ta không tốn mộtphép hoán vị nào

Trường hợp xấu nhất: Dãy ban đầu có thứ tự ngược Ta thấy ngay mỗi lần sosánh phần tử thứ i với n-i phần tử còn lại, ta đều phải thực hiện hoán vị Điều này cónghĩa là số phép hoán vị bằng n(n-1)/2

Tổng kết lại, ta có độ phức tạp của Interchange Sort thuộc O(n 2 ) trong mọi trường hợp.

Trang 11

1.3 BUBBLE SORT

1.3.1/ G iới thiệu sơ lược thuật toán:

Như đã biết về thuật toán Sắp xếp chọn ta thấy rằng sau mỗi vòng lặp ta lựađược một phần tử nhỏ nhất đưa về đầu danh sách, các phần tử còn lại hầu như khôngảnh hưởng Ta thấy rằng kết quả của vòng lặp trước không ảnh hưởng đến vòng lặpsau Trong bài viết này chúng ta sẽ xét tới thuật toán sắp xếp Nổi bọt – Cải tiển hơn

so với Thuật toán sắp xếp chọn

Với thuật toán này, sẽ có 2 vòng lặp lồng nhau Tại mỗi vòng lặp con sẽ chạy

từ cuối danh sách trở về đầu danh sách tại mỗi bước sẽ so sánh 2 phần tử kế cậnnhau nếu phần tử nào nhỏ hơn sẽ được đảo về phía trước Trong mỗi vòng lặp con,phần tử nhỏ nhất sẽ lần lượt được đưa về đầu dòng theo phương pháp tráo đổi – Đúngvới tư tưởng “Nổi bọt” phần tử nhỏ sẽ dần được nổi lên trên cùng Đặc điểm tối ưuhơn so với Sắp xếp chọn là tại mỗi vòng lặp con do có quá trình tráo đổi phần tử nhỏ

về đầu dãy nên các phần tử lớn dần được đưa về cuối dãy và đồng thời những giá trịnhỏ cũng dần được đưa về đầu dãy Đối với phương pháp sắp xếp chọn có tối đa n –

1 lần tráo đổi phần tử, còn trường hợp sắp xếp nổi bọt thì tối đa n*(n-1) lần tráo đổi(Trường hợp danh sách sắp theo thứ tự ngược lại) Nhưng ưu điểm trông thấy rõ củaphương pháp Nổi bọt là sau mỗi bước thì danh sách dần “ổn định” hơn Nên có thểkhông cần chạy hết vòng lặp danh sách đã được theo thứ tự

* Các bước tiến hành như sau:

//input: dãy (a, n)

//output: dãy (a, n) đã được sắp xếp

Bước 1 : i = Vị trí đầu;

Bước 2 : j = Vị trí cuối;//Duyệt từ cuối dãy ngược về vị trí i

Trong khi (j > i) thực hiện:

Nếu a[j]<a[j-1]: a[j]↔a[j-1];//xét cặp phần tử kế cận

j = Vị trí trước(j);

Bước 3 : i = Vị trí kế(i); // lần xử lý kế tiếp

Nếu i = Vị trí cuối: Dừng // Hết dãy.

Ngược lại : Lặp lại Bước 2

* Ví dụ:

Bên dưới là ví dụ sắp xếp mảng số nguyên theo phương pháp nổi bọt đượcthực hiện từng bước Bước 0 là trạng thái ban đầu của danh sách Ta thấy sau mỗibước thì các phần tử đầu tiên lần lượt được đưa vào thứ tự, các phần tử còn lại cũngdần ổn định hơn Đến bước 6 thì đã hoàn thành công việc sắp xếp

Trang 12

1.3.2/ Thuật toán bằng mã giả:

void boublesort(int *a,int n)

Trang 13

Kết quả hiển thị với đầu vào là 1 List các số nguyên :

1.3.4/ Đánh giá thuật toán:

- Thấy ngay số phép so sánh là luôn không đổi, tức không phụ thuộc vào tình trạng ban đầu của dãy Với i bất kỳ, ta luôn phải so sánh V[j] với V[j-1], mà j chạy từ n đến i+1, tức ta tốn n-i phép so sánh Thêm nữa, i chạy từ 1 đến n-1 Vậy ta tính được số phép so sánh tổng cộng: ∑(n-i) với i chạy từ 1 đến n-1 = (n-1) + (n-2) + … + 1 = n(n-1)/2.

- Số phép hoán vị (tương đương 3 phép gán) lại phụ thuộc vào tình trạng ban đầu của dãy Cụ thể như sau:

+ Trường hợp tốt nhất: Dãy ban đầu đã có thứ tự Ta thấy ngay ta không tốn một phép hoán vị nào.

+ Trường hợp xấu nhất: Dãy ban đầu có thứ tự ngược Xét i bất kỳ, ta thấy rằng mỗi lần so sánh a[j] với a[j-1], ta đều phải thực hiện hoán vị Điều này có nghĩa là số phép hoán vị bằng n(n-1)/2.

- Khuyết điểm:

+ Không nhận diện được tình trạng dãy đã có thứ tự hay có thứ tự từngphần

+ Các phần tử nhỏ được đưa về vị trí đúng rất nhanh, trong khi các phần

tử lớn lại được đưa về vị trí đúng rất chậm

Trang 14

1.3.5/ Ước lượng độ phức tạp thuật toán:

- Trường hợp tốt nhất: Dãy ban đầu đã có thứ tự Ta thấy ngay ta không tốn một phép hoán vị nào.

- Trường hợp xấu nhất: Dãy ban đầu có thứ tự ngược Xét i bất kỳ, ta thấy rằng mỗi lần so sánh a[j] với a[j-1], ta đều phải thực hiện hoán vị Điều này có nghĩa là số phép hoán

vị bằng n(n-1)/2.

Tổng kết lại, ta có độ phức tạp của Bubble Sort thuộc O(n 2 ) trong mọi trường hợp.

Trang 15

1.4 INSERTION SORT

1.5.1/ Giới thiệu sơ lược thuật toán:

Sắp xếp chèn (insertion sort) là một thuật toán sắp xếp rất hiệu quả với các

danh sách nhỏ Nó lần lượt lấy các phần tử của danh sách chèn vào vị trí thích hợptrong một danh sách mới đã được sắp

Thuật toán sắp xếp chèn làm việc cũng giống như tên gọi - Nó thực hiện việcquét một tập dữ liệu, với mỗi phân tử, thủ tục kiểm tra và chèn phần tử đó vào vị tríthích hợp trong danh sách đích (chứa các phần tử đứng trước nó đã được sắp xếp)được tiến hành

Phương pháp dễ dàng nhất để thực hiện thuật toán này là dùng hai vùng chứa

dữ liệu khác nhau - tập dữ liệu nguồn và tập dữ liệu mà các phần tử đã sắp xếp đượcchèn vào Tuy nhiên để tiết kiệm bộ nhớ, hầu hết các ứng dụng đều chỉ sử dụng mộttập dữ liệu duy nhất Thuật toán được tiến hành bằng cách dịch chuyển phân tử hiệntại đang xét tuần tự qua những phân tử ở vùng dữ liệu phía trước đã được sắp xếp,phép hoán vị nó với phần tử liền kề được thực hiện một cách lặp lại cho tới khi tiếntới được vị trí thích hợp

Do với mỗi phân tử, insertion sort cần thực hiện so sánh với các phần tử trước

nó nên tối đa số lần duyệt dữ liệu là !N Vì vậy cũng giống như Bubble sort, Insertionsort được coi là có độ phức tạp O(n2) Mặc dù có cùng độ phức tạp, Insertion sorthiệu quả hơn gần như hai lần so với Bubble sort, tuy nhiên vẫn không hiệu quả vớitập dữ liệu lớn

Giả sử ta có dãy a 1 , a 2 , …, an trong đó i phần tử đầu tiên a 1 , a 2 , …, a i đã có thứ tự Ý tưởng của thuật toán là tìm vị trị thích hợp và chèn phần tử a i+1 vào dãy đã có thứ tự trên để

có được một dãy mới có thứ tự Cứ thế, làm đến cuối dãy ta sẽ được một dãy có thứ tự Với dãy ban đầu a 1 , a 2 , …, a n ta có thể coi đoạn chỉ có một phần tử a 1 là một đoạn đã có thứ tự, sau đó ta chèn phần tử a 2 vào dãy a 1 để có dãy a 1 a 2 có thứ tự Tiếp đó, ta lại chèn phần tử a 3 vào dãy a 1 a 2 để có dãy a 1 a 2 a 3 có thứ tự Cứ thế, đến cuối cùng ta chèn phần tử a n vào dãy a 1 a 2 …a n-1 ta sẽ được dãy a 1 a 2 …a n có thứ tự.

* Các bước thực hiện:

//input: dãy (a, n)

//output: dãy (a, n) đã được sắp xếp

 Bước 1: i = 2; // giả sử có đoạn a[0] đã được sắp

 Bước 2: x = a[i]; Tìm vị trí pos thích hợp trong đoạn a[0]

Trang 16

Danh sách con gồm 3 phần tử bên trái 1,3,7 đã được sắp Để tiếp tục sắp xếp phần

tử thứ tư a4 = 6 vào danh sách con đó, ta tìm vị trí thích hợp của nó là sau 3 và trước7

1.5.2/ Thuật toán bằng mã giả:

void insertion_sort(int x[],int length)

Trang 17

Kết quả hiển thị với đầu vào là 1 List các số nguyên :

1.5.4/ Đánh giá thuật toán:

void InsertionSort ( int a[], int n )

Trang 18

Lưu ý: Chèn nhị phân chỉ làm giảm số lần so sánh, không làm giảm số lần dờichỗ.

Ngoài ra, có thể cải tiến giải thuật chèn trực tiếp với phần tử cầm canh đểgiảm điều kiện kiểm tra khi xác định vị trí pos

Các phép so sánh xảy ra trong mỗi vòng lặp tìm vị trí thích hợp pos Mỗi lầnxác định vị trí pos đang xét không thích hợp  dời chỗ phần tử a[pos-1] đến vị trípos

Giải thuật thực hiện tất cả N-1 vòng lặp tìm pos, do số lượng phép so sánh vàdời chỗ này phụ thuộc vào tình trạng của dãy số ban đầu, nên chỉ có thể ước lượctrong từng trường hợp như sau:

1.5.5/ Ước lượng độ phức tạp thuật toán

Ta thấy các phép so sánh xảy ra trong vòng lặp nhằm tìm vị trí thích hợp pos để chèn

x Mỗi lần so sánh mà thấy vị trí đang xét không thích hợp, ta dời phần tử a[pos] sang phải.

Ta cũng thấy số phép gán và số phép so sánh của thuật toán phụ thuộc vào tình trạng của dãy ban đầu Do đó ta chỉ có thể ước lượng như sau:

- Trường hợp tốt nhất: dãy ban đầu đã có thứ tự Ta tìm được ngay vị trí thích hợp để chèn ngay lần so sánh đầu tiên mà không cần phải vô vòng lặp Như vậy, với i chạy từ 2 đến

n thì số phép so sánh tổng cộng sẽ là n-1 Còn với số phép gán, do thuật toán không chạy vào vòng lặp nên xét i bất kỳ, ta luôn chỉ phải tốn 2 phép gán(x = a[i] và a[pos] = x) Từ đây, ta tính được số phép gán tổng cộng bằng 2(n - 1).

- Trường hợp xấu nhất: dãy ban đầu có thứ tự ngược Ta thấy ngay vị trí thích hợp pos luôn là vị trí đầu tiên của dãy đã có thứ tự, và do đó, để tìm ra vị trí này ta phải duyệt hết dãy đã có thứ tự Xét i bất kỳ, ta có số phép so sánh là i-1, số phép gán là (i - 1) + 2 = i +

1 Với i chạy từ 2 đến n, ta tính được số phép so sánh tổng cộng bằng 1 + 2 + … + (n - 1) = n(n - 1)/2 và số phép gán bằng 3 + 4 + + (n + 1) = (n + 4)(n - 1)/2

Tổng kết lại, ta có độ phức tạp của Insertion Sort như sau:

o Trường hợp tốt nhất: O(n)

o Trường hợp xấu nhất O(n 2 )

Ngày đăng: 24/10/2016, 09:16

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w