16
Đ án 01: CÁC THUT TOÁN SP XP Môn C§u Trúc Dœ Li»u & Gi£i Thu“t Lp 11CK2 Ngày 12 tháng 3 năm 2012 1 T/i sao ph£i s›p x‚p dœ li»u? Gi£ sß ta có mºt t“p dœ li»u và ph£i thüc hi»n tác v tìm ki‚m trên t“p dœ li»u này. Ví d, cho m£ng sL nguyên a và ta cƒn tìm sL nguyên k trong m£ng a này. N‚u tìm th§y, tr£ v• ch¿ sL cıa phƒn tß tương øng trong m£ng; ngưæc l/i, tr£ v• -1. Cách đơn gi£n nh§t là sß dng thu“t toán tìm ki‚m tuƒn tü: 1 // Thuat toan tim kiem tuan tu 2 int LinearSearch( int a[], int n, int k) 3 { 4 for ( int i = 0; i < n; i ++) 5 if (a[ i ] == k) 6 return i; 7 return -1; 8 } Th§y ngay đº phøc t/p cıa thu“t toán tìm ki‚m tuƒn tü là O(n). Nhưng n‚u m£ng sL nguyên đã đưæc s›p x‚p theo thø tü thì ta có th” gi£m đº phøc t/p xuLng còn O(log n) b‹ng cách sß dng thu“t toán tìm ki‚m nh phân (binary search): 1

Ex01 Sorting

Embed Size (px)

DESCRIPTION

cấu trúc dữ liệu

Citation preview

Page 1: Ex01 Sorting

Đồ án 01: CÁC THUẬT TOÁN SẮP XẾPMôn Cấu Trúc Dữ Liệu & Giải Thuật

Lớp 11CK2

Ngày 12 tháng 3 năm 2012

1 Tại sao phải sắp xếp dữ liệu?

Giả sử ta có một tập dữ liệu và phải thực hiện tác vụ tìm kiếm trên tập dữliệu này. Ví dụ, cho mảng số nguyên a và ta cần tìm số nguyên k trong mảnga này. Nếu tìm thấy, trả về chỉ số của phần tử tương ứng trong mảng; ngượclại, trả về −1.

Cách đơn giản nhất là sử dụng thuật toán tìm kiếm tuần tự:

1 // Thuat toan tim kiem tuan tu2 i n t LinearSearch ( i n t a [ ] , i n t n , i n t k )3 {4 f o r ( i n t i = 0 ; i < n ; i++)5 i f ( a [ i ] == k)6 re turn i ;7 re turn −1;8 }

Thấy ngay độ phức tạp của thuật toán tìm kiếm tuần tự là O(n). Nhưngnếu mảng số nguyên đã được sắp xếp theo thứ tự thì ta có thể giảmđộ phức tạp xuống còn O(log n) bằng cách sử dụng thuật toán tìm kiếm nhịphân (binary search):

1

Page 2: Ex01 Sorting

1 // Thuat toan tim kiem nhi phan , a l a mang da duoc sap xep tangdan

2 i n t BinarySearch ( i n t a [ ] , i n t n , i n t k )3 {4 i n t l e f t = 0 ;5 i n t r i g h t = n − 1 ;6 whi le ( l e f t <= r i gh t )7 {8 i n t mid = l e f t + ( r i gh t − l e f t ) / 2 ;9 i f ( k > a [ mid ] )

10 l e f t = mid + 1 ;11 e l s e i f ( k < a [ mid ] )12 r i g h t = mid − 1 ;13 e l s e14 re turn mid ;15 }16 re turn −1;17 }

Ta thấy thuật toán tìm kiếm nhị phân chạy nhanh hơn thuật toán tìmkiếm tuần tự, nhưng tập dữ liệu cần phải được sắp xếp sẵn. Do đó, nếu tathường xuyên phải thực hiện tác vụ tìm kiếm trên một tập dữ liệu thì chiếnlược khôn ngoan là: thực hiện sắp xếp dữ liệu trước; và từ đó về sau, tadùng thuật toán tìm kiếm nhị phân. Thật vậy, giả sử ta phải thực hiện mlần tìm kiếm trên mảng dữ liệu có kích thước n. Nếu dùng thuật toán tìmkiếm tuần tự thì tổng thời gian thực hiện là O(mn). Nhưng, nếu ta thực hiệnsắp xếp dữ liệu trước trong khoảng thời gian T (n) (với T là một hàm nàođó), và sau đó dùng thuật toán tìm kiếm nhị phân thì tổng thời gian sẽ làO(T (n) +m log n): nhanh hơn nhiều so với O(mn) khi m lớn.

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

Trong bài này, ta xét bài toán sắp xếp tăng dần.

2.1 Bubble Sort

Bubble (n): Sự nổi bọt.

2

Page 3: Ex01 Sorting

2.1.1 Ý tưởng

Bubble Sort chia mảng thành hai phần: phần đã được sắp và phần chưađược sắp. Ban đầu, phần đã được sắp không có phần tử nào, phần chưađược sắp gồm nguyên mảng a[0..n-1].

Ta tiến hành mở rộng dần phần được sắp như sau:

• Lần xử lý thứ 1: ta duyệt từ cuối đến đầu phần chưa được sắp để đưaphần tử nhỏ nhất trong phần chưa được sắp (lúc này là phần tử

NHỎ NHẤT của mảng) “nổi” lên đầu phần chưa được sắp. Sau bướcnày, phần được sắp có được phần tử đầu tiên: chính là phần tử vừa

“nổi” lên - phần tử NHỎ NHẤT của mảng. Phần chưa được sắp thuhẹp lại một phần tử.

• Lần xử lý thứ 2: ta lại duyệt từ cuối đến đầu phần chưa được sắp đểđưa phần tử nhỏ nhất trong phần chưa được sắp (lúc này là

phần tử NHỎ THỨ HAI của mảng) “nổi” lên đầu phần chưa được sắp.Sau bước này, phần được sắp mở rộng sang phải một phần tử: chính là

phần tử vừa “nổi” lên - phần tử NHỎ THỨ HAI của mảng. Phần chưađược sắp thu hẹp lại một phần tử.

• . . .

• Cứ thế cho đến khi phần được sắp gồm a[0..n-2], phần chưa đượcsắp chỉ còn một phần tử là a[n-1]: sắp xếp xong!

“Ta duyệt từ cuối đến đầu phần chưa được sắp để đưa phần tử nhỏnhất trong phần chưa được sắp “nổi” lên đầu phần chưa được sắp”: cụthể như thế nào?

Giả sử phần chưa được sắp hiện thời là a[i..n-1]. Ta đưa phần tử nhỏnhất trong a[i..n-1] “nổi” lên đầu bằng cách duyệt từ cuối về đầu như sau:

1 f o r ( i n t j = n−1; j > i ; j−−)2 {3 i f ( a [ j ] < a [ j −1])4 {5 Swap( a [ j ] , a [ j −1]) ; // Hoan v i6 }7 }

3

Page 4: Ex01 Sorting

2.1.2 Thuật toán

1 void BubbleSort ( i n t a [ ] , i n t n)2 {3 f o r ( i n t i = 0 ; i < n−1; i++) // Phan chua duoc sap l a a [ i . . n−1]4 {5 // Dua phan tu nho nhat trong phan chua duoc sap ‘ ‘ no i ’ ’ l en

dau6 f o r ( i n t j = n−1; j > i ; j−−)7 {8 i f ( a [ j ] < a [ j −1])9 {

10 Swap( a [ j ] , a [ j −1]) ; // Hoan v i11 }12 }13 }14 }

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

• Thấy ngay trong mọi trường hợp số phép so sánh luôn là:n−2∑i=0

n− i− 1 = n(n− 1)/2 = O(n2)

• Số phép hoán vị (1 phép hoán vị = 3 phép gán):

– Trường hợp xấu nhất: khi mảng ban đầu có thứ tự ngược, lúc nàyta tốn

∑n−2i=0 n− i− 1 = n(n− 1)/2 = O(n2) phép hoán vị.

– Trường hợp tốt nhất: khi mảng ban đầu đã có thứ tự, lúc này tatốn 0 phép hoán vị.

• Khuyết điểm của Bubble Sort:

– Không nhận diện được tình trạng mảng ban đầu đã có thứ tự(hoặc có thứ tự từng phần).

– Trong khi các phần tử nhỏ được đưa về vị trí đúng rất nhanh thìcác phần tử lớn được đưa về vị trí đúng rất chậm.

→ Thuật toán Shaker Sort khắc phục các khuyết điểm này của BubbleSort.

4

Page 5: Ex01 Sorting

2.2 Shaker Sort

Shaker (n): Sàng lắc (lắc qua trái, lắc qua phải).

2.2.1 Ý tưởng

Như đã nói ở trên, Shaker Sort là cải tiến của Bubble Sort. Với Bubble Sort,phần được sắp nằm ở đầu mảng và mở rộng dần sang phải; mỗi lần xử lý,chỉ mở rộng thêm một phần tử. Với Shaker Sort, phần được sắp nằm ở cảđầu và cuối mảng và mở rộng dần từ cả đầu và cuối vào giữa. Hơnnữa, ở mỗi lần xử lý, Shaker Short “khôn ngoan” hơn Bubble Sort: nó nhậndiện được tình trạng đã có thứ tự từng phần của mảng và nhờ đó, có thểmở rộng hơn một phần tử.

Ban đầu, phần được sắp đầu mảng và cuối mảng không có phần tử nào,

phần chưa được sắp gồm nguyên mảng a[0..n-1]. Ở mỗi lần xử lý, ta mởrộng dần phần được sắp từ cả đầu và cuối vào giữa như sau:

• Lượt đi:

– Ta duyệt từ cuối về đầu phần chưa được sắp a[l..r] để đưa phầntử nhỏ nhất trong phần chưa được sắp “nổi” lên đầu phần chưađược sắp. Quá trình duyệt này giống như Bubble Sort: so sánhhai cặp phần tử kế cận a[j] và a[j-1], nếu a[j] < a[j-1] thìhoán vị a[j] và a[j-1]. Tuy nhiên, Shaker Sort “khôn ngoan”hơn: nó lưu lại chỉ số j ứng với lần xảy ra hoán vị sau cùng (tahãy gọi là j_lastSwap); bằng cách này, nếu phần đầu của phầnchưa được sắp đã có thứ tự, chẳng hạn a[i..k], thì Shaker Sortsẽ nhận diện được tình trạng này (k = j_lastSwap - 1).

– Mở rộng phần đã sắp đầu mảng sang phải: thay vì chỉ luộn mởrộng sang phải 1 phần tử như ở Bubble Sort, ta sẽ mở rộng đếnphần tử j_lastSwap - 1. Như vậy, phía trái của phần chưa đượcsắp sẽ thu hẹp lại: l = j_lastSwap.

• Lượt về:

– Ta duyệt từ đầu về cuối phần chưa được sắp a[l..r] để đưa phầntử lớn nhất trong phần chưa được sắp “chìm” xuống cuối phầnchưa được sắp. Quá trình duyệt này tương tự Bubble Sort: sosánh hai cặp phần tử kế cận a[j] và a[j+1], nếu a[j] > a[j+1]

5

Page 6: Ex01 Sorting

thì hoán vị a[j] và a[j+1]. Giống như trên, ta cũng lưu lại chỉsố j_lastSwap ứng với lần xảy ra hoán vị sau cùng.

– Mở rộng phần đã sắp cuối mảng sang trái: mở rộng đến phần tửj_lastSwap + 1. Như vậy, phía phải của phần chưa được sắp thuhẹp lại: r = j_lastSwap.

Cứ thế, ta tiến hành xử lý nhiều lần . . . cho đến khi l >= r (phần chưađược sắp chỉ còn một phần tử hoặc không còn phần tử nào): sắp xếp xong!

2.2.2 Thuật toán

1 void ShakerSort ( i n t a [ ] , i n t n)2 {3 i n t l = 0 ;4 i n t r = n − 1 ;5 i n t j_lastSwap = n − 1 ; // Luu ch i so ung vo i lan hoan v i sau

cung6

7 whi le ( l < r )8 {9 // ====== Bat dau luo t d i ======

10 // 1 . Dua phan tu nho ‘ ‘ no i ’ ’ l en dau11 f o r ( i n t j = r ; j > l ; j−−)12 {13 i f ( a [ j ] < a [ j −1])14 {15 Swap( a [ j ] , a [ j −1]) ;16 j_lastSwap = j ;17 }18 }19 // 2 . Thu hep phia t r a i cua phan chua duoc sap20 l = j_lastSwap ;21 // ====== Ket thuc luo t d i ======22

23 // ====== Bat dau luo t ve ======24 // 1 . Dua phan tu lon ‘ ‘ chim ’ ’ xuong cuo i25 f o r ( i n t j = l ; j < r ; j++)26 {27 i f ( a [ j ] > a [ j +1])28 {29 Swap( a [ j ] , a [ j +1]) ;30 j_lastSwap = j ;31 }

6

Page 7: Ex01 Sorting

32 }33 // 2 . Thu hep phia phai cua phan chua duoc sap34 r = j_lastSwap ;35 // ====== Ket thuc luo t ve ======36 }37 }

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

• Trường hợp xấu nhất: khi mảng ban đầu có thứ tự ngược. Trong trườnghợp này, nó giống như Bubble Sort: tốn O(n2) phép so sánh và O(n2)phép hoán vị.

• Shaker Sort chỉ tốt hơn Bubble Sort khi mảng ban đầu đã có thứ tựhoặc có thứ tự từng phần. Trong trường hợp tốt nhất là mảng ban đầuđã có thứ tự, Shaker Sort nhận diện ra ngay tình trạng này sau lượt điđầu tiên và kết thúc thuật toán; nó chỉ tốn n− 1 = O(n) phép so sánhvà không tốn phép hoán vị nào.

2.3 Selection Sort

Selection (n): Sự chọn lựa.

2.3.1 Ý tưởng

Selection Sort chia mảng thành 2 phần: phần đã được sắp và phần chưađược sắp. Ban đầu, phần đã được sắp không có phần tử nào, phần chưa

được sắp gồm nguyên mảng a[1..n-1]. Ở mỗi bước xử lý, ta mở rộng dầnphần được sắp (và do đó, thu hẹp dần phần chưa được sắp) như sau: taCHỌN phần tử nhỏ nhất trong phần chưa được sắp và hoán vị nó với phầntử đầu tiên của phần chưa được sắp. Sau bước này, phần được sắp mở rộngsang phải một phần tử (chính là phần tử đầu tiên của phần chưa được sắp);phần chưa được sắp thu hẹp lại một phần tử. Cứ thế, ta tiến hành xử lýnhiều lần . . . cho đến khi phần được sắp gồm a[1..n-2], phần chưa đượcsắp chỉ còn một phần tử a[n-1]: sắp xếp xong!

7

Page 8: Ex01 Sorting

2.3.2 Thuật toán

1 void S e l e c t i o nSo r t ( i n t a [ ] , i n t n)2 {3 f o r ( i n t i = 0 ; i < n−1; i++) // Phan chua sap : a [ i . . n−1]4 {5 // 1 . Tim phan tu nho nhat trong phan chua sap6 i n t min = i ;7 f o r ( i n t j = i +1; j < n ; j++)8 {9 i f ( a [ j ] < a [ min ] )

10 {11 min = j ;12 }13 }14 // 2 . Hoan v i phan tu nho nhat vo i phan tu dau15 i f (min != i )16 {17 Swap( a [ i ] , a [ min ] ) ;18 }19 }20 }

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

• Để tìm phần tử nhỏ nhất trong phần chưa sắp a[i..n-1], ta phải thựchiện n-i-1 phép so sánh. Do vậy, trong mọi trường hợp, số phép sosánh luôn là:

∑n−2i=0 (n− i− 1) = n(n− 1)/2 = O(n2).

• Số phép hoán vị:

– Trường hợp xấu nhất: O(n) (khi mảng ban đầu có thứ tự ngược).

– Trường hợp tốt nhất: 0 (khi mảng ban đầu đã có thứ tự).

2.4 Insertion Sort

Insertion (n): Sự chèn vào.

8

Page 9: Ex01 Sorting

2.4.1 Ý tưởng

Insertion Sort chia mảng thành hai phần: phần đã được sắp và phần chưađược sắp. Ban đầu, phần đã được sắp chỉ có một phần tử là a[0], phần

chưa được sắp gồm các phần tử còn lại a[1..n-1]. Ở mỗi lần xử lý, ta mởrộng dần phần đã sắp bằng cách lấy ra phần tử đầu tiên của phần chưa sắp

và CHÈN vào vị trí thích hợp trong phần đã sắp sao cho: sau khi chèn phầnđã sắp vẫn giữ nguyên tính thứ tự. Cứ thế, ta tiến hành xử lý nhiều lần. . . cho đến khi phần đã sắp gồm a[0..n-1], phần chưa sắp không còn phầntử nào: sắp xếp xong!

2.4.2 Thuật toán

1 void I n s e r t i o nSo r t ( i n t a [ ] , i n t n)2 {3 i n t temp ; // Bien de luu l a i g i a t r i cua phan tu can chen4 f o r ( i n t i = 1 ; i < n ; i++)5 {6 temp = a [ i ] ; // Luu l a i g i a t r i cua phan tu can chen7 // Tim v i t r i trong phan da sap de chen temp8 i n t j ;9 f o r ( j = i −1; j >= 0 && a [ j ] > temp ; j−−)

10 {11 a [ i +1] = a [ i ] ; // Dich chuyen cac phan tu cua phan da sap

sang phai12 }13 a [ j +1] = temp ; // Chen14 }15 }

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

• Trường hợp xấu nhất: khi mảng ban đầu có thứ tự ngược. Lúc này,để chèn phần tử a[i] (với i chạy từ 1 đến n-1) vào phần đã sắpa[0..i-1], ta luôn phải so sánh a[i] với tất cả phần tử của phầnđã sắp, dịch chuyển tất cả các phần tử của phần đã sắp sang phảivà chèn a[i] vào vị trí 0. Do đó, trong trường hợp xấu nhất, ta tốn:1 + 2 + 3 + · · · + (n − 1) = n(n − 1)/2 = O(n2) phép so sánh và dịchchuyển.

9

Page 10: Ex01 Sorting

• Trường hợp tốt nhất: khi mảng ban đầu đã có thứ tự. Ta chỉ tốn: O(n)phép so sánh và 0 phép dịch chuyển.

2.5 Quick Sort

Quick (a): nhanh!

2.5.1 Ý tưởng

Nhận xét chung về 4 thuật toán Bubble Sort, Shaker Sort, Selection Sort,Insertion Sort:

• Đơn giản, dễ cài đặt.

• Tuy nhiên, chi phí còn cao (O(n2)) và do đó, không thích hợp cho việcsắp xếp các mảng lớn → Cần có những thuật toán hiệu quả hơn choviệc sắp xếp các mảng lớn. Quick Sort là một trong những thuật toánnhư thế.

Quick Sort là một thuật toán sắp xếp có dạng “chia để trị” (devide and

conquer). Ý tưởng chính của Quick Sort gồm có 3 bước:

1. Phân chia dãy cần sắp thành 2 phần có thứ tự với nhau: ta sắp xếplại các phần tử trong dãy cần sắp a[l..r] để cho có một chỉ số m với

l<= m <= r thỏa: với mọi i = l..m-1 thì a[i] < a[m] VÀ với mọi i

= m+1..r thì a[i] >= a[m]

2. Thực hiện sắp xếp đệ qui trên phần bên trái a[l..m-1]

3. Thực hiện sắp xếp đệ qui trên phần bên phải a[m+1..r]

2.5.2 Thuật toán

1 void QSWithRange( i n t a [ ] , i n t l , i n t r )2 {3 // Chi xu ly khi day co > 1 phan tu4 i f ( l < r )5 {6 // 1 . Chia day a [ l e f t . . r i g h t ] thanh 2 phan7 i n t m = l − 1 ;8 f o r ( i n t i = l ; i < r ; i ++)

10

Page 11: Ex01 Sorting

9 {10 i f ( a [ i ] < a [ r ] )11 {12 Swap( a[++m] , a [ i ] ) ;13 }14 }15 Swap( a[++m] , a [ r ] ) ;16 // 2 . Sap xep phan ben t r a i17 QSWithRange(a , l , m−1) ;18 // 3 . Sap xep phan ben phai19 QSWithRange(a , m+1, r ) ;20 }21 }22

23 void QuickSort ( i n t a [ ] , i n t n)24 {25 QSWithRange( i n t a [ ] , 0 , n−1) ;26 }

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

Trong hàm QSWithRange, ta chọn phần tử “chuẩn” (pilot) là phần tử ở cuốidãy a[r] và phân chia dãy thành hai phần có thứ tự với nhau dựa vào phầntử “chuẩn này”. Việc chọn lựa phần tử “chuẩn” đóng vai trò rất quantrọng.

Xét trường hợp tốt nhất: phần tử “chuẩn” phân chia dãy a[l..r] thànhhai phần có kích thước xấp xỉ nhau. Vì bước phân chia tốn thời gian là O(n)nên dễ thấy thời gian chạy của Quick Sort là T (n) = O(n) + 2T (n/2). Giảira ta được T (n) = O(n log n).

Xét trường hợp xấu nhất: nếu dãy ban đầu đã có thứ tự hoặc có thứ tựngược thì phần tử “chuẩn” là phần tử lớn nhất hoặc nhỏ nhất trong dãy; dođó, nó phân chia dãy ban đầu thành 2 dãy: 1 dãy không có phần tử nào, 1dãy có n− 1 phần tử. Vì vậy, thời gian chạy sẽ là T (n) = O(n) + T (n− 1).Giải ra ta được T (n) = O(n2).

Giả sử ta không quá “xui”: mỗi lần phân chia, phần tử “chuẩn” phânchia dãy thành 2 phần có kích thước là 9n/10 và n/10. Ta có: T (n) =O(n)+T (9n/10)+T (n/10). Giải ra ta vẫn được T (n) = O(n log n): phần tử“chuẩn” như thế vẫn tốt.

11

Page 12: Ex01 Sorting

Vậy thì ta có thể cải tiến thuật toán Quick Sort được cài đặt ở trênbằng cách: thay vì luôn chọn a[r] làm phần tử “chuẩn”, ta chọn ngẫu nhiênmột phần tử trong a[l..r] làm phần tử “chuẩn”. Bằng cách này, trong mọitrường hợp, xác suất T (n) = O(n log n) là rất cao.

Thuật toán Quick Sort với chọn phần tử “chuẩn” ngẫu nhiên (ta gọi làRandomized Quick Sort):

1 void RQSWithRange( i n t a [ ] , i n t l , i n t r )2 {3 // Chi xu ly khi day co > 1 phan tu4 i f ( l < r )5 {6 // 0 . Chon ngau nhien phan tu ‘ ‘ chuan ’ ’7 i n t ranNum = rand ( ) % ( r−l +1) ;8 Swap( a [ l+ranNum ] , a [ r ] ) ;9

10 // 1 . Chia day a [ l e f t . . r i g h t ] thanh 2 phan11 i n t m = l − 1 ;12 f o r ( i n t i = l ; i < r ; i ++)13 {14 i f ( a [ i ] < a [ r ] )15 {16 Swap( a[++m] , a [ i ] ) ;17 }18 }19 Swap( a[++m] , a [ r ] ) ;20 // 2 . Sap xep phan ben t r a i21 QSWithRange(a , l , m−1) ;22 // 3 . Sap xep phan ben phai23 QSWithRange(a , m+1, r ) ;24 }25 }26

27 void RandomizedQuickSort ( i n t a [ ] , i n t n)28 {29 srand ( ( unsigned ) time (0 ) ) ;30 RQSWithRange( i n t a [ ] , 0 , n−1) ;31 }

12

Page 13: Ex01 Sorting

3 Yêu cầu của đồ án

3.1 Tóm tắt sơ bộ

• Các bạn sẽ cài đặt 6 thuật toán (Bubble Sort, Shaker Sort, SelectionSort, Insertion Sort, Quick Sort, Randomized Quick Sort) ở trên và tìmhiểu, cài đặt thêm thuật toán Merge Sort.

• Sau khi cài đặt xong 7 thuật toán, các bạn sẽ tiến hành các thí nghiệmđể có thể thấy được thời gian thực thi của mỗi thuật toán ứng với mỗitình trạng dữ liệu đầu vào cũng như là so sánh thời gian thực thi của

các thuật toán với nhau. Ở đây, ta xét 4 trình trạng dữ liệu đầu vào:

– Đã có thứ tự.

– Có thứ tự ngược.

– Ngẫu nhiên.

– Gần như có thứ tự.

3.2 Cụ thể

Nội dung nộp của các bạn gồm có 2 phần: phần code (5đ) và phần báo cáo(5đ).

3.2.1 Phần code (5 điểm)

Ta sẽ thí nghiệm với 4 tình trạng dữ liệu: đã có thứ tự (sorted), có thứ tựngược (reversed), ngẫu nhiên (random), và gần như có thứ tự (nearly sorted).Với mỗi tình trạng, ta khảo sát 5 kích thước dữ liệu (số phần tử) khác nhau:1000, 3000, 10000, 30000, 100000.

Với mỗi tình trạng dữ liệu state,với mỗi kích thước dữ liệu size,với mỗi thuật toán sắp xếp sortAlg, chương trình của các bạncần phải:1. Tạo mảng dữ liệu có tình trạng state và có kích thước size.

13

Page 14: Ex01 Sorting

2. Sắp xếp mảng dữ liệu này bằng thuật toán sortAlg

và đo thời gian thực thi của sortAlg.3. Xuất kết quả sắp xếp ra file:- Mỗi phần tử cách nhau khoảng trắng.- Tên file đặt theo định dạng: <sortAlg>_<state>_<size>.txt

Ví dụ: QuickSort_NearlySorted_1000.txt

Các file kết quả: ngoài các file lưu kết quả sắp xếp như đã nói ở trên, đểtiện lợi cho việc thống kê kết quả, chương trình của các bạn cũng cần phảixuất thời gian thực thi của tất cả các lần chạy ở trên ra một file chung:

• Ta qui ước đặt tên file này là Result.csv. Định dạng *.csv có thể mởbằng Excel, sẽ dễ dàng cho việc vẽ đồ thị.

• File Result.csv sẽ có dạng như hình 1. Trong đó, ở mỗi dòng, ô đầutiên là tình trạng dữ liệu ban đầu, ô thứ hai là kích thước dữ liệu, cácô tiếp theo là thời gian thực thi của các thuật toán (mình mới chỉ điềnđại bằng tay hai dòng đầu tiên để minh họa, chương trình của các bạncần điền hết tất cả các ô thời gian thực thi).

Hình 1: Minh họa file Result.csv

14

Page 15: Ex01 Sorting

• Ghi kết quả ra file *.csv như thế nào? Nếu ta mở file *.csv ở trênbằng Notepad++ thì sẽ thấy như hình 2. Như vậy, thực chất mỗi ôtrên một dòng cách nhau bởi dấu phẩy. Ví dụ, ta có thể ghi dòng thứ2 bằng câu lệnh:

1 f p r i n t f ( f , "Random,1000 , 0 , 0 , 0 , 0 , 0 , 0 , 0\ n" ) ;

Hình 2: File Result.csv mở bằng Notepad++

3.2.2 Phần báo cáo (5 điểm)

Gồm có các nội dung sau:

1. Trình bày về thuật toán mà các bạn tự tìm hiểu thêm là Merge Sort(ýtưởng, thuật toán, đánh giá thuật toán) (1 điểm).

2. Trình bày về kết quả thí nghiệm (1 điểm) và cho nhận xét (3 điểm).Cách trình bày kết quả thí nghiệm: thay vì đưa ra các con số về thờigian chạy, ta nên trực quan hóa bằng đồ thị; như vậy, sẽ dễ quan sátvà nhận xét hơn. Các bạn sẽ vẽ 4 đồ thị ứng với 4 tình trạng dữ liệuđầu vào. Trong đó, mỗi đồ thị có trục tung là kích thước dữ liệu, trụchoành là thời gian chạy (có dạng như hình 3).

15

Page 16: Ex01 Sorting

Hình 3: Minh họa dạng đồ thị

4 Một số qui định

• Cấu trúc thư mục nộp bài: trong thư mục <MSSV> gồm có:

1. Thư mục Code: chứa toàn bộ project (xóa thư mục debug, file*.ncb).

2. Thư mục Result: chứa toàn bộ các file kết quả.

3. File Report.doc(x) hoặc Report.pdf.

• Môi trường lập trình: Visual Studio 2008 hoặc 2010.

• Lưu ý: Những trường hợp giống bài nhau sẽ bị 0 điểm.

16