báo cáo bài tập phân tích và thiết kế thuật toán đề tài tìm hiểu các thuật toán sắp xếp cơ bản

29 0 0
Tài liệu đã được kiểm tra trùng lặp
báo cáo bài tập phân tích và thiết kế thuật toán đề tài tìm hiểu các thuật toán sắp xếp cơ bản

Đ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

Tuy nhiên, với 1 cuốn từ điển được sắp xếp theo thứ tự alphabet thì công việc tra cứu là khá dễ dàng.Lấy 1 ví dụ khác, nếu như bạn được cho một danh sách điểm của sinh viên toàn trường,

Trang 1

TRƯỜNG ĐẠI HỌC XÂY DỰNGKHOA CÔNG NGHỆ THÔNG TIN

BÁO CÁO BÀI TẬP

PHÂN TÍCH VÀ THIẾT KẾ THUẬT TOÁNĐề tài: Tìm hiểu các thuật toán sắp xếp cơ bản.

1 Vũ Xuân Hoàn.2 Triệu Việt Hùng.3 Đào Thanh Hiệp.4 Trần Văn Mạnh.5 Lê Thị Thùy Trang.

Trang 2

Mục lục

Phần I: Phần mở đầu 4

1.1 Nêu vấn đề: 4

1.2 Mục đích của đề tài: 4

1.3 Phạm vi nghiên cứu của đề tài: 5

Phần II: Cơ sở lý thuyết 5

2.1 Các khái niệm cơ bản 5

2.1.1 Bài toán (Problem) 5

2.1.2 Thuật toán (Algorithm) 5

3.1.1 Ý tưởng thuật toán 7

3.1.2 Mô tả thuật toán 7

3.2.1 Ý tưởng thuật toán 12

3.2.2 Mô tả thuật toán 12

3.2.3 Ví dụ 13

3.2.4 Phân tích độ phức tạp 15

3.2.5 Chứng minh tính đúng 15

3.2.6 Code java & Thực nghiệm 16

3.3 Sắp xếp nổi bọt (Bubble sort) 18

3.3.1 Ý tưởng thuật toán 18

3.3.2 Mô tả thuật toán 19

3.3.3 Ví dụ 19

Trang 3

3.3.4 Phân tích độ phức tạp 20

3.3.5 Chứng minh tính đúng 21

3.3.6 Code java & Thực nghiệm 22

3.4 Sắp xếp đổi chỗ trực tiếp (Interchange sort) 23

3.4.1 Ý tưởng thuật toán 23

3.4.2 Mô tả thuật toán 23

Trang 4

Phần I: Phần mở đầu

1.1 Nêu vấn đề:

Hiện nay trong hầu hết các hệ lưu trữ, quản lí dữ liệu, thao tác tìm kiếm thường đượcthực hiện nhiều nhất để khai thác thông tin một cách nhanh chóng Để phục vụ cho việc tìm kiếm nhanh chóng thì dữ liệu cần được sắp xếp theo trật tự nhất định.

Để rõ làm rõ hơn cho câu hỏi “Tại sao cần phải sắp xếp?” thì hãy thử tượng tượng: Bạn cần tra cứu 1 từ trong từ điển, tuy nhiên cuốn từ điển đó lại không được sắp xếp theo thứ tự alphabet, các từ trong từ điển được sắp xếp theo 1 quy luật ngẫu nhiên Khi đó, việc bạn phải làm là lật từng trang và mỗi trang bạn lại phải cố tìm kiếm xem từ cần tìm có trong trang đó hay không Việc này khiến bạn phải bỏ ra khá nhiều thời gian và công sức Tuy nhiên, với 1 cuốn từ điển được sắp xếp theo thứ tự alphabet thì công việc tra cứu là khá dễ dàng.

Lấy 1 ví dụ khác, nếu như bạn được cho một danh sách điểm của sinh viên toàn trường, yêu cầu đặt ra là tìm sinh viên có điểm số cao nhất, khi đó việc bạn phải làm là duyệt qua từng sinh viên và tìm ra sinh viên có điểm số cao nhất, công việc này khá dễ dàng và hoàn toàn có thể thực hiện được, thế nhưng câu chuyện không dừng lại ở đó Bởi nếu công việc yêu cầu là lọc ra top 10 sinh viên có điểm số cao nhất để phục vụ công tác khen thưởng, với 1 danh sách chưa được sắp xếp bạn sẽ phải lần lượt tìm ra sinh viên có điểm số cao thứ nhất, thứ 2, thứ 3, việc này cũng làm cho bạn tốn rất nhiều thời gian và công sức, đặc biệt khi số lượng sinh viên trong danh sách càng tăng thì thời gian và công sức bạn bỏ ra cũng tỉ lệ thuận theo số lượng đó Tuy nhiên với một danh sách sinh viên với điểm số đã được sắp xếp (giả sử sắp xếp theo thứ tự giảm dần), thì công việc của bạn đơn giản là lấy ra 10 sinh viên đầu tiên trong danh sách

Qua những ví dụ trên có thể thấy rằng, sắp xếp khiến cho những thao tác tìm kiếm hay lọc của chúng ta trở nên dễ dàng hơn rất nhiều Chính vì vậy, sắp xếp là một trong những bài toán quan trọng trong lập trình Trong lập trình hiện tại có không dưới 20 thuật toán phục vụ cho công việc sắp xếp.

Trang 5

Qua đó hiểu rõ ưu nhược điểm của các phương pháp sắp xếp để so sánh tốc độ sắp xếp.

1.3 Phạm vi nghiên cứu của đề tài:

Nội dung của bài báo cáo dưới đây là 4 thuật toán sắp xếp cơ bản:- Sắp xếp chèn (Insertion sort)

- Sắp xếp chọn (Selection sort)- Sắp xếp nổi bọt (Bubble sort)

- Sắp xếp đổi chỗ trực tiếp (Interchange sort)

Phần II: Cơ sở lý thuyết

2.1 Các khái niệm cơ bản.

2.1.1 Bài toán (Problem)

Bài toán là một việc nào đó mà con người muốn máy tính thực hiện nhằm cho ra kết quả.

Bài toán được xác định bởi 2 yếu tố cơ bản:

- Đầu vào (Input): cung cấp thông tin dữ liệu đã có.- Đầu ra (Output): những thông tin cần tìm/cần xác định.

2.1.2 Thuật toán (Algorithm)

Thuật toán là một dãy hữu hạn các thao tác được sắp xếp theo một trình tự nhất định sao cho sau khi thực hiện dãy thao tác đó từ Input của bài toán ta nhận được Output cần tìm.

Một số đặc trưng của thuật toán:- Tính tổng quát.

- Tính dừng.- Tính xác định.- Tính hiệu quả.

Một số phương pháp mô tả thuật toán:- Liệt kê từng bước.

- Sơ đồ khối.

- Giả mã (pseudo code).

Trang 6

Những vấn đề cần quan tâm khi nghiên cứu thuật toán:- Giải được bằng thuật toán.

- Tối ưu hóa thuật toán.- Cách triển khai thuật toán

Phương pháp thực nghiệm: Lập trình và thử trên các ví dụ

Phương pháp lý thuyết: Tính toán thời gian, bộ nhớ, … cần thiết của một thuật toán dựa trên độ lớn của input.

- Ưu điểm của phương pháp lý thuyết:

o Không phụ thuộc ngôn ngữ lập trình, loại máy tính.

o Biết được tính hiệu quả của thuật toán đối với các dữ liệu có kích thước lớn

Các quy tắc đánh giá độ phứ tạp của thuật toán:- Quy tắc hằng số.

- Quy tắc cộng.- Quy tắc lấy max.- Quy tắc nhân.

2.2.2 Chứng minh tính đúng

Các chiến lược chứng minh tính đúng (correctness):- Kiểm thử: Chạy thử thuật toán với các dữ liệu vào cụ thể.

o Ưu điểm: Dễ thực hiện.

o Nhược điểm: Có thể không phát hiện được hết các lỗi.- Chứng minh tính đúng: Chứng minh bằng toán học.

o Ưu điểm: Tổng quát.

Trang 7

o Nhược điểm: Khó hơn và vẫn có thể có lỗi.- Kết hợp kiểm thử và chứng minh tính đúng.

Đối với thuật toán đệ quy, sử dụng phương pháp quy nạp:

- Chứng minh tính đúng của thuật toán theo kích thước dữ liệu vào.- Cơ sở của quy nạp: Trường hợp đơn giản nhất.

- Giả thiết quy nạp: Thuật toán đúng với dữ liệu kích thước n- Tổng quát: Thuật toán đúng với dữ liệu kích thước n + 1

Đối với thuật toán không đệ quy, sử dụng bất biến vòng lặp (loop invariant):- Xác định bất biến vòng lặp sao cho: bất biến vòng lặp đúng ở lần lặp cuối cùng

kéo theo thuật toán đúng.

- Chứng minh bất biến đúng ở lần lặp đầu tiên.

- Chứng minh bất biến đúng ở lần lặp trước thì cũng đúng ở lần lặp sau.

Phần III: Các thuật toán sắp xếp cơ bản3.1 Sắp xếp chèn (Insertion sort)

3.1.1 Ý tưởng thuật toán

Thuật toàn này thực hiện bằng cách duyệt qua từng phần tử của mảng và sắp xếp nó vào đúng vị trí trong mảng con (mảng từ phần tử đầu tiền đến phần tử đang xét) sao cho được một dãy số được sắp xếp theo đúng yêu cầu bài toàn.

3.1.2 Mô tả thuật toán

Giả sử: Cho mảng A có n phần tử chưa sắp xếp, yêu cầu bài toàn là sắp xếp mảng A theo thứ tự tăng dần

Bước 1: Khởi tạo mảng con (mảng đã sắp xếp) có k = 1 phần tử là phần tử đầu tiên trong mảng chưa sắp xếp (có chỉ số i = 0)

Bước 2: Nếu i<n đặt key = A[i] và chuyển sang bước 3, nếu i=n thì chuyển sang Bước 5.

Bước 3: Xét các phần tử trong mảng con từ 0 đến j = i-1.

Trang 8

- Nếu không có phần tử nào trong mảng con nhỏ hơn A[i] thì dịch chuyển tất cả các phần tử trong mảng con về sau một đơn vị và đặt vị trí đầu tiên của mảng con.

- Nếu không có phần tử nào lớn hơn A[i] thì thêm vào mảng con phần tử A[i] vào vị trí cuối cùng.

- Nếu trong mảng con xuất hiện phần tử lớn hơn và phần tử nhỏ hơn A[i] thì dịch chuyển tất cả các phần tử lớn hơn A[i] về sau một vị trí so với vị trí ban đầu đồng thời đặt A[i] vào vị trí kế tiếp sau phần tử nhỏ hơn A[i].

Bước 4: i=i+1 và quay lại bước 2.

Bước 5: kết thúc thuật toàn và in ra mảng con vừa thu được.Mô tả bằng pseudo code (mã giả):

3.1.3 Ví dụ

Sắp xếp mảng A = [4,3,2,10,12,1,5,6] theo thứ tự tăng dần:

Trang 9

Hàng đầu tiên là mảng ban đầu chưa sắp xếp,từ hàng thứ hai đến bảy là ta thực hiện chèn số đang xét vào vị trí thích hợp của mảng con theo yêu cầu bài toàn đặt ra.

Sau khi triển khai thuật toán Insertion Sort với với mảng A theo yêu cầu sắp xếp tăngdần ta được dòng cuối cùng là mảng A sau khi sắp xếp A = [1,2,3,4,5,6,10,12].

Trang 10

3.1.4 Phân tích độ phức tạp

For(int i=1;i<n;i++){

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

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

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

arr[j+1] = key;}

- Trong trường hợp tốt (dãy khởi tạo ban đầu đã được xếp theo thứ tự) thì không phải chạy vòng while nào nên (z=0) độ phức tạp của thuật toàn là :

O(n)*(O(1)+O(1)) = O(n)

- Trong trường hợp xấu (dãy khởi tạo ban đầu có thứ tự bị ngược so với yêu cầu bài toán) thì z nhận giá trị n-x ( x là số nguyên và <1x<=n) nên độ phức tạp của thuật toàn là :

Trang 11

- Kích thước mảng trong khoảng (55, 60, …,100):Kích

thước mảng

Thời gian chạy trungbình trong 10 lần test (s)

E-7 1.4E-7 1.5E-7 1.7E-7 1.2E-7 1.2E-7 1.5E-7 1.7E-7 1.8E-7 1.9E-7

Đồ thị thời gian chạy thuật toán:

Trang 12

3.2 Sắp xếp chọn (Selection sort)

3.2.1 Ý tưởng thuật toán

Selection Sort (sắp xếp chọn) là một thuật toán sắp xếp đơn giản dựa trên so sánh tại chỗ, trong đó:

- Danh sách được chia thành hai phần (Trái - Phải) (Vẫn là cùng một mảng).- Phần được sắp xếp ở đầu bên trái và phần chưa được sắp xếp ở đầu bên phải.- Lúc đầu thì phần bên phải là toàn bộ danh sách (Vì phần bên trái chưa sắp xếp).- Mỗi lần lặp chúng ta sẽ liên tục tìm giá trị nhỏ nhất ở phần bên phải, hoán đổi vị trí của

nó cho phần tử ngoài cùng bên trái.

Quá trình này tiếp tục di chuyển qua lại mảng chưa được sắp xếp bởi một phần tử sang phải.

3.2.2 Mô tả thuật toán

- Giả sử, ta chọn được phần tử có giá trị nhỏ nhất nhất trên mảng là A[k] với vị trí là k.- Tráo đổi A[0] với A[k], vậy thì lúc này ta sẽ nhận được A[0] là phần tử có giá trị nhỏ

- Giả sử đến bước thứ i ta đã có A[0] <= A[1] <= <= A[i-1] Bây giờ ta cần tìm thành phần có giá trị nhỏ nhất trong các phần tử từ A[i] đến A[n-1].

Trang 13

- Giả sử phần tử đó có vị trí là t có giá trị A[t] sao cho i <= t <= n – 1.- Ta lại tráo đổi A[i] với A[t] Lặp lại cho tới i = n – 1.

- Cuối cùng, ta có mảng A được sắp xếp.

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 trung bình.Khi bạn sắp xếp với một cơ sở dữ liệu lớn thì quá trình này sẽ chậm và tốn nhiều bộ nhớ máy tính.

Độ phức tạp của selection sort là: O(n2).Mô tả bằng pseudo code (mã giả):Program Selection_Sort;

Read N;i:=1;

WHILE i<=N DORead A[i];i:=i+1;ENDWHILE;

FOR i:=0 to N-1 DOmin_idx:=i;FOR j:=i+1 to N DO

IF A[j] < A[min_idx] THENmin_idx = j;ENDIF;

swap(A[i], A[min_idx]);ENDFOR;

3.2.3 Ví dụ

Trang 14

- Mảng ban đầu là: 8 5 2 6 9 3 1 4 0 7- Bắt đầu thực hiện thuật toán:

i=0: Tìm lần lượt trong dãy số nhỏ nhất rồi đổi chỗ cho phần tử A[0].Dãy mới là: 0 5 2 6 9 3 1 4 8 7

i=1: Tìm lần lượt trong dãy số nhỏ nhất rồi đổi chỗ cho phần tử A[1].Dãy mới là: 0 1 2 6 9 3 5 4 8 7

i=2: Tìm lần lượt trong dãy số nhỏ nhất rồi đổi chỗ cho phần tử A[2] (số 2 nằm đúng vị trí nên không phải đổi chỗ).

Trang 15

i=7: Tìm lần lượt trong dãy số nhỏ nhất rồi đổi chỗ cho phần tử A[7].Dãy mới là: 0 1 2 3 4 5 6 7 8 9

i=8: Tìm lần lượt trong dãy số nhỏ nhất rồi đổi chỗ cho phần tử A[8] (số 8 nằm đúng vị trí nên không đổi chỗ).

int temp = arr[min_idx]; arr[min_idx] = arr[j]; arr[j] = temp;}

Thời gian thực thi là O(n ) (do 2 vòng for lồng vào nhau).2

- Để 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 ) 2phé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 ) phép2gá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(n ) trong 2mọi trường hợp.

3.2.5 Chứng minh tính đúng

Trang 16

- Bất biến vòng lặp: Sau lần lặp thứ i = k ta có: Dãy con A = (A[0],…,A[k]) đã được sắp xếp (*).

- Sau lần lặp thứ i = 2 ta có dãy con A = (A[0],…,A[2]) đã được sắp xếp → (*) đúng.

- Giả sử sau lần lặp thứ i = k ta có: dãy con A = (A[0],…,A[k]) đã được sắp xếp → Sau lần thứ i = k+1 ta có: dãy con A = (A[0],…,A[k],A[k+1]) đã được sắp xếp.Kết luận: Thuật toán đúng trong mọi trường hợp.

3.2.6 Code java & Thực nghiệm

Kết quả chạy được ở Terminal:

Trang 17

Bảng kết quả:

- Kích thước mảng trong khoảng (5, 10, 15, …,50):Kích

Thờigianchạytrungbìnhtrong 10

lần test(s)

- Kích thước mảng trong khoảng (55, 60, …,100):

Trang 18

Thời gianchạy trungbình trong10 lần test

Đồ thị thời gian chạy thuật toán:

3.3 Sắp xếp nổi bọt (Bubble sort)

Giải thuật sắp xếp nổi bọt(Bubble Sort) là một trong những thuật toán phân loại đơn giảnnhất mà chúng ta có thể sử dụng để sắp xếp một mảng hoặc một cấu trúc Giải thuật sắpxếp này được tiến hành dựa trên việc so sánh cặp phần tử liền kề nhau và tráo đổi thứ tự nếuchúng không theo thứ tự Giải thuật này không thích hợp sử dụng với các tập dữ liệu lớn khi

Trang 19

Giải thuật sắp xếp nổi bọt là giải thuật chậm nhất trong số các giải thuật sắp xếp cơ bản.Giải thuật này còn chậm hơn giải thuật đổi chỗ trực tiếp mặc dù số lần so sánh bằng nhau,nhưng do đổi chỗ hai phần tử kề nhau nên số lần đổi chỗ nhiều hơn.

3.3.1 Ý tưởng thuật toán

- Ý chính của thuật toán là xuất phát từ cuối (hoặc đầu) dãy, đổi chổ các cặp phầntử kế cận để đưa phần tử nhỏ (lớn) hơn trong cặp phần tử đó về vị trí đúng đầu(cuối) dãy hiện hành, sau đó sẽ không xét đến nó ở vòng lặp tiếp theo, do vậy ởlần xử lý thứ i sẽ có vị trí đầu dãy là i Lặp lại xử lý trên cho đến khi không còncặp phần tử nào để xét.

3.3.2 Mô tả thuật toán

Procedure bubbleSort(list L, number n) For number i from 0 to n – 1

For number j from 1 to n – i – 1If L[j] < L[j + 1]

Swap(L[j], L[j + 1])Endif

3.3.3 Ví dụ

Sắp xếp dãy sau tăng dần ( 8 1 4 3 5 2 7 )Ta có :

o Input: 8 1 4 3 5 2 7o Output:1 2 3 4 5 7 8

Chi tiết các vòng lặp được thể hiện dưới bảng sau

Trang 20

i = 00

(n−i+1 )=n(n−1)2

- Số lượng phép hoán vị thực hiện tùy thuộc vào kết quả so sánh, có thể ước lượng trong từng trường hợp như sau:

Trang 21

A’[1] ≤ A’ ≤ A’ ≤ … ≤ A’ ( n = length(A) )[2][3][n]

Để thể hiện điều đó chúng ta chứng minh A’ cũng có các yếu tố của A nhưng theothứ tự đã sắp xếp

- Bất biến vòng lặp:o Vòng lặp bên trong:

Khi bắt đầu mỗi lần lặp, mảng con A[j…n] bao gồm các phần tử banđầu A[j…n] nhưng theo một thứ tự khác và phần tử cuối là lớn nhất

Thuộc tính gữi cho sự bất biến:

Ban đầu mảng chỉ có phần tử A[j] là phần tử lớn nhất của mảng con.

Trong mỗi vòng lặp so sánh A[j] và A[j+1] và đổi chỗ làm saocho A[j+1] lớn hơn A[j] Vì vậy sau khi lặp lại vòng lặp thì phần tử cuối là phần tử lớn nhất của mảng con

Vòng lặp kết thúc khi j = n – i – 1 Tại thời điểm đó, độ dài mảng con cũng tăng lên một và phần tử cuối cùng là phần tử nhỏ nhất khi mảng con chúng ta hoán đổi A[n-i-1] và A[n-i-2]o Vòng lặp bên ngoài:

Khi bắt đầu mỗi lần lặp, mảng con A[0…i-1] bao gồm các phần tử nhỏ hơn các phần tử trong mảng con A[i…n] theo thứ tự đã sắp xếp

Thuộc tính gữi cho sự bất biến:

Ban đầu mảng con A[0…i-1] rỗng và đây là phần tử nhỏ nhất của mảng

Sau khi thực hiện vòng lặp bên trong, A[n] sẽ là phần tử lớn nhất của mảng A[i…n] Và ở vòng lặp bên ngoài, A[n-i-1…n] bao gồm các phần tử lớn hơn các phần tử của A[0…n-i-2], mảng con A[n-i-1…n] sẽ bao gồm các phần tử lớn hơn các phần tử của A[0…n-i-2]

Trang 22

Vòng lặp kết thúc khi i = n-1 Tại thời điểm đó mảng A[0…n] sẽ bao gồm các phần tử đã được sắp xếp

3.3.6 Code java & Thực nghiệm

a Bảng kết quả

Số phần tử Thời giant trung bình

10 lần chạy(nano giây) phần tửSố 10 lần chạy(nano giây)Thời giant trung bình

Trang 23

3.4 Sắp xếp đổi chỗ trực tiếp (Interchange sort)

3.4.1 Ý tưởng thuật toán

Xét bài toán trong TH sắp xếp tăng dần

- Xét đôi một phần tử hiện tại với tất cả phần tử còn lại phía sau của dãy Nếu cặp là nghịch thế thì tiến hành hoán vị.

- Lặp lại như trên với các phần tử còn lại của dãy.Nghịch thế: Ai, Aj với Ai > Aj, i < j,

→ Tức Ai đứng trước Aj và giá trị Ai lớn hơn Aj.

3.4.2 Mô tả thuật toán

(Liệt kê các bước)

Bước 1: Chọn phần tử đầu của dãy (kích thước = n)

Bước 2: Xét cặp phần tử đầu tiên với phần tử tiếp theo trong dãyBước 3: Kiểm tra nếu cặp là nghịch thế thì tiến hành hoán vị.Bước4: Lặp lại bước 2 với tất cả các phần tử còn lại trong dãyBước 5: Lặp lại bước 1 với dãy có kích thước n = n – 1

Ngày đăng: 20/05/2024, 17:42

Tài liệu cùng người dùng

Tài liệu liên quan