Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 32 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
32
Dung lượng
493,79 KB
Nội dung
Chương II TÌM KIẾM VÀSẮPXẾPTRONG II.1. Giới thiệu về sắpxếpvàtìm kiếm II.1.1. Sắpxếp a. Định nghĩa sắpxếp Cho dãy X gồm n phần tử x 1 , x 2 , ., x n có cùng một kiểu dữ liệu T 0 . Sắp thứ tự n phần tử này là một hoán vị các phần tử thành dãy x k1 , x k2 , ., x kn sao cho với một hàm thứ tự f cho trước, ta có : f(x k1 ) ∝ f(x k2 ) ∝ . ∝ f(x kn ). trong đó: ∝ là một quan hệ thứ tự. Ta thường gặp ∝ là quan hệ thứ tự " ≤ " thông thường. b. Phân loại phương pháp sắpxếp Dựa trên tiêu chuẩn lưu trữ dữ liệu ở bộ nhớ trong hay ngoài mà ta chia các phương pháp sắpxếp thành hai loại: * Sắpxếptrong : Với các phương pháp sắpxếp trong, toàn bộ dữ liệu được đưa vào bộ nhớ trong (bộ nhớ chính). Đặc điểm của phương pháp sắpxếptrong là khối lượng dữ liệu bị hạn chế nhưng bù lại, thời gian sắpxếp lại nhanh. * Sắpxếp ngoài : Với các phương pháp sắpxếp ngoài, toàn bộ dữ liệu được lưu ở bộ nhớ ngoài. Trong quá trình sắp xếp, chỉ một phần dữ liệu được đưa vào bộ nhớ chính, phần còn lại nằm trên thiết bị trữ tin. Đặc điểm của loại sắpxếp ngoài là khối lượng dữ liệu ít bị hạn chế, nhưng thời gian sắpxếp lại chậ m (do thời gian chuyển dữ liệu từ bộ nhớ phụ vào bộ nhớ chính để xử lý và kết quả xử lý được đưa trở lại bộ nhớ phụ thường khá lớn). c. Vài qui uớc về kiểu dữ liệu khi xét các thuật toán sắpxếp Thông thường, T 0 có kiểu cấu trúc gồm m trường thành phần T 1 , T 2 , …, T m . Hàm thứ tự f là một ánh xạ từ miền trị của kiểu T 0 vào miền trị của một số thành phần { T ik } 1 ≤ ik ≤ p , trên đó có một quan hệ thứ tự α. Không mất tính tổng quát, ta có thể giả sử f là ánh xạ từ miền trị của T 0 vào miền trị của một thành phần dữ liệu đặc biệt (mà ta gọi là khóa- key) , trên đó có một quan hệ thứ tự α. Khi đó, kiểu dữ liệu chung T 0 của các phần tử x i thường được cài đặt bởi cấu trúc: typedef struct { KeyType key; DataType Data; } ElementType; Khi đó bài toán đưa về sắpxếp dãy {x i .key} 1≤i≤n . Tìm kieám vaø saép xeáp trong II.2 Để đơn giản trong trình bày, ta có thể giả sử T 0 chỉ gồm trường khóa, α là quan hệ thứ tự ≤ thông thường và f là hàm đồng nhất và ta chỉ cần xét các phương pháp sắpxếp tăng trên dãy đơn giản {x i } 1≤i≤n . Trong chương này, khi xét các phương pháp sắpxếp trong, dãy x thường được lưu trong mảng tĩnh như sau: #define MAX_SIZE … // Kích thước tối đa của mảng cần sắp theo thứ tự tăng typedef ElementType; // Kiểu dữ liệu chung cho các phần tử của mảng typedef ElementType mang[MAX_SIZE] ; // Kiểu mảng mang x; Trong phần cài đặt các thuật toán sắpxếp sau này, ta thường sử dụng các phép toán: đổi chỗ HoánVị(x,y), gán Gán(x,y), so sánh SoSánh(x,y) nh ư sau: void HoánVị(ElementType &x, ElementType &y) { ElementType tam; Gán(tam, x); Gán(x, y); Gán(y, tam); return ; } void Gán(ElementType &x, ElementType y) { // Gán y vào x, tùy từng kiểu dữ liệu mà ta có phép gán cho hợp lệ return; } int SoSánh(ElementType x, ElementType y) { // Hàm trả về trị: 1 nếu x > y // 0 nếu x == y // -1 nếu x < y // tùy theo kiểu ElementType mà ta dùng các quan hệ <, >, == cho hợp lệ } Tỡm kieỏm vaứ saộp xeỏp trong II.3 Khi ỏnh giỏ phc tp ca mi thut toỏn sp xp, ta thng ch tớnh s ln so sỏnh khúa (SS), s ln hoỏn v khúa (HV) hoc s ln Gỏn (G) trong thut toỏn ú. II.1.2. Tỡm kim a. nh ngha tỡm kim Cho trc mt phn t Item v dóy X gm n phn t x 1 , x 2 , ., x n u cú cựng kiu T 0 . Bi toỏn tỡm kim l xem Item cú mt trong dóy X hay khụng? (hay tng quỏt hn: xem trong dóy X cú phn t no tha món mt tớnh cht TC cho trc no ú liờn quan n Item hay khụng?) b. Phõn loi cỏc phng phỏp tỡm kim Cng tng t nh sp xp, ta cng cú 2 loi phng phỏp tỡm kim trong v ngoi tựy theo d liu c lu tr b nh trong hay ngoi. Vi tng nhúm phng phỏp, ta li phõn bit cỏc phng phỏp tỡm kim tựy theo d li u ban u ó c sp hay cha. Chng hn i vi trng hp d liu ó c sp v lu b nh trong, ta cú 2 phng phỏp tỡm kim: tuyn tớnh hay nh phõn. Khi ci t cỏc thut toỏn tỡm kim, ta cng cú cỏc qui c tng t cho kiu d liu v cỏc phộp toỏn c bn trờn kiu ú nh i vi cỏc phng phỏp sp xp ó trỡnh by trờn. Trong ch ng ny, ta ch hn ch xột cỏc phng phỏp tỡm kim v sp xp trong. II.2. Phng phỏp tỡm kim trong Bi toỏn : Input : - dóy X = {x 1 , x 2 , ., x n } gm n mc d liu - Item: mc d liu cn tỡm cựng kiu d liu vi cỏc phn t ca X Output: Tr v: - tr 0, nu khụng thy Item trong X - v trớ u tiờn i (1 i n) trong X sao cho x i Item. II.2.1. Phng phỏp tỡm kim tuyn tớnh a. Dóy cha c sp i vi dóy bt k cha c sp th t, thut toỏn tỡm kim n gin nht l tỡm tun t t u n cui dóy. Tìm kieám vaø saép xeáp trong II.4 • Thuật toán int TìmTuyếnTính(x, n, Item) - Bước 1: VịTrí = 1; - Bước 2: if ((VịTrí ≤ n) and (x VịTrí != Item)) { VịTrí = VịTrí + 1; Quay lại đầu bước 2; } else chuyển sang bước 3; - Bước 3: if (VịTrí > n) VịTrí = 0; //không thấy Trả về trị VịTrí; • Cài đặt int TìmTuyếnTính (mang x, int n, ElementType Item) { int VịTrí = 0; while ((VịTrí < n) && (x[VịTrí] != Item)) VịTrí = VịTrí + 1 ; if (VịTrí ≥ n) VịTrí = 0; //không thấy else VịTrí++; return(VịTrí); } * Chú ý: Để cài đặt thuật toán trên (cũng tương tự như thế với các thuật toán tiếp theo) với danh sách tuyến tính nói chung thay cho cách cài đặt danh sách bằng mảng, ta chỉ cần thay các câu lệnh hay biểu thức sau: VịTrí = 1; VịTrí = VịTrí + 1; (VịTrí ≤ n) ; x VịTrí ; trong thuật toán tương ứng bởi: ĐịaChỉ = ĐịaChỉ phần tử (dữ liệu) đầu tiên; ĐịaChỉ = ĐịaChỉ phần tử kế tiếp; (ĐịaChỉ != ĐịaChỉ kết thúc); Dữ liệu của phần tử tại ĐịaChỉ; * Độ phức tạp của thuật toán tìm kiếm tuyến tính (trên dãy chưa được sắp) trong trường hợp: - tốt nhất (khi Item ≡ x 1 ): T tốt (n) = O(1) - tồi nhất (khi không có Item trong dãy hoặc Item chỉ trùng với x n ): T xấu (n) = O(n) - trung bình: T tbình (n) = O(n) * Thuật toán tìm kiếm tuyến tính cải tiến bằng kỹ thuật lính canh Để giảm bớt phép so sánh chỉ số trong biểu thức điều kiện của lệnh if hay while trong thuật toán trên, ta dùng thêm một biến phụ đóng vai trò lính canh bên phải (hay trái) x n+1 = Item (hay x 0 = Item). • Thuật toán int TìmTuyếnTính_CóLínhCanh(x, n, Item) Tìm kieám vaø saép xeáp trong II.5 - Bước 1: VịTrí = 1; x n+1 = Item; // phần tử cầm canh - Bước 2: if (x VịTrí != Item) { VịTrí = VịTrí + 1; Quay lại đầu bước 2; } else chuyển sang bước 3; - Bước 3: if (VịTrí == n+1) VịTrí = 0; // thấy giả hay không thấy ! Trả về trị VịTrí; • Cài đặt int TìmTuyếnTính_CóLínhCanh(mang x, int n, ElementType Item) { int VịTrí = 0; x[n] = Item; // phần tử cầm canh while (x[VịTrí] != Item) VịTrí = VịTrí + 1; if (VịTrí == n) VịTrí = 0; // thấy giả hay không thấy ! else VịTrí++; return(VịTrí); } b. Dãy đã được sắp Đối với dãy đã được sắp thứ tự (không mất tính tổng quát, ta có thể giả sử tăng dần), ta có thể cải tiến thuật toán tìm kiếm tuyến tính có lính canh như sau: ta sẽ dừng việc tìm kiếm khi tìm thấy hoặc tại thời điểm i đầu tiên gặp phần tử x i mà: x i ≥ Item. • Thuật toán int TìmTuyếnTính_TrongMảngĐãSắp_CóLínhCanh(a, Item, n) - Bước 1: VịTrí = 1; x n+1 = Item; // phần tử cầm canh - Bước 2: if (x VịTrí < Item) { VịTrí = VịTrí + 1; Quay lại đầu bước 2; } else chuyển sang bước 3; - Bước 3: if ((VịTrí == n+1) or (VịTrí < n+1 and x VịTrí > Item)) VịTrí = 0; // thấy giả hoặc không thấy ! Trả về trị VịTrí; • Cài đặt int TìmTuyếnTính_TrongMảngĐãSắp_CóLínhCanh (mang x, ElementType Item, int n) { int VịTrí = 0; x[n] = Item; // phần tử cầm canh while (x[VịTrí] < Item) VịTrí = VịTrí + 1; if (VịTrí < n && (x[VịTrí] == Item)) VịTrí++; else VịTrí = 0; // thấy giả hoặc không thấy ! return(VịTrí); Tìm kieám vaø saép xeáp trong II.6 } * Tuy có tốt hơn phương pháp tìm kiếm tuyến tính trong trường hợp mảng chưa được sắp, nhưng trong trường hợp này thì độ phức tạp trung bình vẫn có cấp là n: T tbình = O(n) Đối với mảng đã được sắp, để giảm hẳn độ phức tạp trong trường hợp trung bình và kể cả trường hợp xấu nhất, ta sử dụng ý tưởng “chia đôi” thể hiện qua phương pháp tìm kiếm nhị phân sau đây. II.2.2. Phương pháp tìm kiếm nhị phân . Ý tưởng của phương pháp: Trước tiên, so sánh Item với phần tử đứng giữa dãy x giữa , nếu thấy (Item = x giữa ) thì dừng; ngược lại, nếu Item < x giữa thì ta sẽ tìm Item trong dãy con trái: x 1 , …, x giữa-1 , nếu không ta sẽ tìm Item trong dãy con phải: x giữa+1 , …, x n . Ta sẽ thể hiện ý tưởng trên thông qua thuật toán lặp sau đây. • Thuật toán int TìmNhịPhân(x, Item, n) - Bước 1: ChỉSốĐầu = 1; ChỉSốCuối = n; - Bước 2: if (ChỉSốĐầu <= ChỉSốCuối) { ChỉSốGiữa = (ChỉSốĐầu + ChỉSốCuối)/2; // lấy thương nguyên if (Item == x ChỉSốGiữa ) Chuyển sang bước 3; else { if (Item < x ChỉSốGiữa ) ChỉSốCuối = ChỉSốGiữa -1; else ChỉSốĐầu = ChỉSốGiữa +1; Quay lại đầu bước 2; // Tìm tiếp trong nửa dãy con còn lại } } - Bước 3: if (ChỉSốĐầu <= ChỉSốCuối) return (ChỉSốGiữa); else return (0); // Không thấy • Cài đặt int TimNhiPhan(mang x, ElementType Item, int n) { int Đầu = 0, Cuối = n-1; while (Đầu ≤ Cuối) { Giữa = (Đầu + Cuối)/2; if (Item == x[Giữa]) break; else if (Item < x[Giữa]) Cuối = Giữa -1 else Đầu = Giữa + 1; } if (Đầu ≤ Cuối) return (Giữa+1); else return (0); Tỡm kieỏm vaứ saộp xeỏp trong II.7 } Da trờn ý tng qui ca thut toỏn, ta cng cú th vit li thut toỏn trờn di dng qui, tt nhiờn khi ú s lóng phớ b nh hn ! Ti sao ? (xem nh bi tp). phc tp ca thut toỏn trong trng hp trung bỡnh v xu nht: T tbỡnh (n) = T xu (n) = O(log 2 n) Do ú i vi dóy c sp, phng phỏp tỡm kim nh phõn s hiu qu hn nhiu so vi phộp tỡm kim tuyn tớnh, c bit khi n ln. II.3. Phng phỏp sp xp trong Cú 3 nhúm chớnh cỏc thut toỏn sp xp trong (n gin v ci tin): * Phng phỏp sp xp chn (Selection Sort): Trong nhúm cỏc phng phỏp ny, ti mi bc, dựng cỏc phộp so sỏnh, ta chn phn t cc tr ton cc (nh nht hay ln nht) ri t nú vo ỳng v trớ mỳt tng ng ca dóy con cũn li cha sp (phng phỏp chn trc tip). Trong quỏ trỡnh chn, cú th xỏo trn cỏc ph n t cỏc khong cỏch xa nhau mt cỏch hp lý (sao cho nhng thụng tin ang to ra bc hin ti cú th cú ớch hn cho cỏc bc sau) thỡ s c phng phỏp sp chn ci tin HeapSort. * Phng phỏp sp xp i ch (Exchange Sort): Thay vỡ chn trc tip phn t cc tr ca cỏc dóy con, trong phng phỏp sp xp i ch, mi bc ta dựng cỏc phộp hoỏn v liờn tip trờn cỏc c p phn t k nhau khụng ỳng th t xut hin cỏc phn t ny mỳt ca cỏc dóy con cũn li cn sp (phng phỏp ni bt BubbleSort, ShakeSort). Nu cng s dng cỏc phộp hoỏn v nhng trờn cỏc cp phn t khụng nht thit luụn k nhau mt cỏch hp lý thỡ ta nh v ỳng c cỏc phn t (khụng nht thit phi luụn mộp cỏc dóy con c n sp) v s thu c phng phỏp QuickSort rt hiu qu. * Phng phỏp sp xp chốn (Insertion Sort): Theo cỏch tip cn t di lờn (Down-Top), trong phng phỏp chốn trc tip, ti mi bc, xut phỏt t dóy con liờn tc ó c sp, ta tỡm v trớ thớch hp chốn vo dóy con ú mt phn t mi thu c mt dóy con mi di hn vn c sp ( phng phỏp chốn trc tip). Thay vỡ chn cỏc dóy con liờn tc c sp di hn, nu ta chn cỏc dóy con cỏc v trớ cỏch xa nhau theo mt qui lut khong cỏch gim dn hp lý thỡ s thu c phng phỏp sp chốn ci tin ShellSort. II.3.1. Phng phỏp sp xp chn n gin Tìm kieám vaø saép xeáp trong II.8 a. Ý tưởng phương pháp Với mỗi bước lặp thứ i (i = 1, ., n-1) chọn trực tiếp phần tử nhỏ nhất x min_i trong từng dãy con có thể chưa được sắp x i , x i+1 , ., x n và đổi chỗ phần tử x min_i với phần tử x i . Cuối cùng, ta được dãy sắp thứ tự x 1 , x 2 , ., x n. Ví dụ : Sắpxếp tăng dãy: 44, 55, 12, 42, 94, 18, 06, 67 Ở bước thứ 1 (i=1), tìm được x min_1 = x 7 = 6, đổi chỗ, x min_1 với x 1 : 44, 55, 12, 42, 94, 18, 06, 67 Kết qủa sau mỗi bước lặp: i = 1 : 06 55 12 42 94 18 44 67 i = 2 : 06 12 55 42 94 18 44 67 i = 3 : 06 12 18 42 94 55 44 67 i = 4 : 06 12 18 42 94 55 44 67 i = 5 : 06 12 18 42 44 55 94 67 i = 6 : 06 12 18 42 44 55 94 67 i = 7 : 06 12 18 42 44 55 67 94 b. Thuật toán SắpXếpChọn(x, n) - Bước 1: i = 1; - Bước 2: Tìm phần tử x ChiSoMin nhỏ nhất trong dãy x i , x i+1 , ., x n Hoán Vị x i và x ChiSoMin ; // Chuyển phần tử nhỏ nhất vào vị trí của x i -Bước 3: if (i < n) { i = i+1; Quay lại đầu bước 2; } else Dừng; c. Cài đặt void SắpXếpChọn(mang x, int n) { int ChiSoMin; for (int i = 0; i < n -1 ; i++) { ChiSoMin = i; for (int j = i + 1; j < n; j++) if (x[j] < x[ChiSoMin]) ChiSoMin = j; if (ChiSoMin > i) HoánVị(x[i],x[ChiSoMin]); } return; } d. Độ phức tạp thuật toán + Do, trong mọi trường hợp, ở bước thứ i ( ∀ i = 1, ., n-1) luôn cần n-i phép so sánh khóa nên: SS xấu = SS tốt = ∑ − = 1 1 n i (n-i) = 2 )1( −nn Tìm kieám vaø saép xeáp trong II.9 + Trong trường hợp xấu nhất (khi dãy đã được sắp theo thứ tự ngược lại), ở bước thứ i ta phải đổi chỗ khóa 1 lần : HV xấu = ∑ − = 1 1 n i 1 = n -1 + Trong trường hợp tốt nhất (khi dãy đã được sắp), ở bước thứ i ta không phải đổi chỗ khóa lần nào: HV tốt = ∑ − = 1 1 n i 0 = 0 Tóm lại, độ phức tạp thuật toán: T(n) = T tốt (n) = T xấu (n) = O(n 2 ). II.3.2. Phương pháp sắpxếp chèn đơn giản a. Ý tưởng phương pháp: Giả sử dãy x 1 , x 2 , ., x i-1 đã được sắp thứ tự. Khi đó, tìm vị trí thích hợp để chèn x i vào dãy x 1 , x 2 , ., x i-1 , sao cho dãy mới dài hơn một phần tử x 1 , x 2 , …, x i-1 , x i vẫn được sắp thứ tự. Thực hiện cách làm trên lần lượt với mỗi i = 2, 3, ., n, ta sẽ thu được dãy có thứ tự. Ví du : Sắpxếp dãy 67, 33, 21, 84, 49, 50, 75. Kết qủa sau mỗi bước lặp: i=2 33 67 21 84 49 50 75 i=3 21 33 67 84 49 50 75 i=4 21 33 67 84 49 50 75 i=5 21 33 49 67 84 50 75 i=6 21 33 49 50 67 84 75 i=7 21 33 49 50 67 75 84 b. Nội dung thuật toán Để tăng tốc độ tìm kiếm (bằng cách giảm số biểu thức so sánh trong điều kiện lặp), ta dùng thêm lính canh bên trái x 0 = x i trong việc tìm vị trí thích hợp để chèn x i vào dãy đã sắp thứ tự x 1 , x 2 , ., x i-1 để được một dãy mới vẫn tăng x 1 , x 2 , ., x i-1 , x i , (với i = 2, ., n). SắpXếpChèn(x, n) - Bước 1: i = 2; // xuất phát từ dãy x 1 , x 2 , ., x i-1 đã được sắp - Bước 2: x 0 = x i ; // lưu x i vào x 0 - đóng vai trò lính canh trái Tìm vị trí j thích hợp trong dãy x 1 , x 2 , ., x i-1 để chèn x i vào; //vị trí j đầu tiên từ phải qua trái bắt đầu từ x i-1 sao cho x j ≤ x 0 -Bước 3: Dời chỗ các phần tử x j+1 , ., x i-1 sang phải một vị trí; if (j < i-1) x j+1 = x 0 ; -Bước 4: if (i < n) { i = i+1; Quay lại đầu bước 2; } else Dừng; c. Cài đặt thuật toán Tìm kieám vaø saép xeáp trong II.10 Áp dụng một mẹo nhỏ, có thể áp dụng (một cách máy móc !) ý tưởng trên để cài đặt thuật toán trong C (bài tập). Lưu ý rằng trong C hay C++, với n phần tử của mảng x[i], i được đánh số bắt đầu từ 0 tới n -1; do đó, để cài đặt thuật toán này, thay cho lính canh trái như trình bày ở trên, ta sẽ dùng lính canh bên phải x n+1 (≡ x[n]) và chèn x i thích hợp vào dãy đã sắp tăng x i+1 , ., x n để được một dãy mới vẫn tăng x i , x i+1 , ., x n , với mọi i = n-1, ., 1. void SắpXếpChèn(mang x, int n) { for ( int i = n -2 ; i >= 0 ; i--) { x[n] = x[i]; // lính canh phải j = i+1; while (x[ j ] < x[n]) { x[ j-1] = x[ j ]; // dời x[ j] qua trái một vị trí j++; } if (j > i+1) x[ j-1] = x[n]; } return ; } Có thể cải tiến việc tìm vị trí thích hợp để chèn x i bằng phép tìm nhị phân (bài tập). d. Độ phức tạp của thuật toán + Trường hợp tồi nhất xảy ra khi dãy có thứ tự ngược lại: để chèn x i cần i lần so sánh khóa với x i-1 , ., x 1 , x 0 . SS xấu = ∑ = n i i 2 = 2 )1( +nn -1 HV xấu = ∑ = + n i i 2 3/)1( = 6 )3( +nn - 3 2 + Trong trường hợp tốt nhất (khi dãy đã được sắp): HV tốt = ∑ = n i 2 3/1 = (n -1)/3 SS tốt = ∑ = n i 2 1 = n -1 Tóm lại, độ phức tạp thuật toán: T tốt (n) = O(n). T xấu (n) = O(n 2 ). II.3.3. Phương pháp sắpxếp đổi chỗ đơn giản (phương pháp nổi bọt hay Bubble Sort) a. Ý tưởng phương pháp: Duyệt dãy x 1 , x 2 , ., x n . Nếu x i > x i+1 thì hoán vị hai phần tử kề nhau x i và x i+1 . Lặp lại quá trình duyệt (các phần tử “nặng” - hay lớn hơn - sẽ “chìm xuống dưới” hay chuyển dần về cuối dãy) cho đến khi không còn xảy ra việc hoán vị hai phần tử nào nữa. Ví dụ : Sắpxếp tăng dãy : [...]... phõn hoch thỡ sp xp xong phc tp trong mi ln phõn hoch l O(n) Vy: Ttt (n) = O(nlog2n) + Trong trng hp trung bỡnh thỡ : Ttbỡnh(n) = O(nlog2n) Tỡm kieỏm vaứ saộp xeỏp trong II.19 QuickSort l phng phỏp sp xp trong trờn mng rt hiu qu c bit cho n nay II.3.7 Phng phỏp sp xp trờn cõy cú th t (HeapSort) Vi phng phỏp sp xp Quick Sort, thi gian thc hin trung bỡnh khỏ tt, nhng trong trng hp xu nht nú vn l O(n2)... 16, ) sp xp mt dóy gm n i tng, cn ũi hi log2n thao tỏc Tỏch v mi i tng trong n mc phi c x lý trong mi thao tỏc Do ú, phc tp trong trng hp ti nht l: Txu(n) = O(nlog2n) - Phng phỏp trn t nhiờn hiu qa v mt thi gian nhng tn b nh ph cho cỏc dóy ph Da trờn ý tng ca phng phỏp trn t nhiờn, nu dóy c ci t bng danh sỏch liờn kt (s trỡnh by trong chng sau) thỡ nhc im trờn s c khc phc - Cú th ci biờn phng phỏp... toỏn ShakerSort(x, n) Tỡm kieỏm vaứ saộp xeỏp trong II.13 - Bc 1: L = 1; R = n; - Bc 2: * Bc 2a: // Duyt t di lờn y phn t nh v u dóy: L j = R; ChSLu = R; Trong khi (j > L) thc hin: { if (xj < xj-1) { Hoỏn v xj v xj-1; ChSLu = j; } j = j -1; } L = ChSLu; // Khụng xột cỏc phn t ó sp u dóy * Bc 2b:// Duyt t trờn xung y phn t ln v cui dóy: R j = L; ChSLu = L; Trong khi (j < R) thc hin: { if (xj > xj+1)... R ChSLu = L; for (j = L; j < R; j++) Tỡm kieỏm vaứ saộp xeỏp trong II.14 { if (x[ j ] > x[ j +1]) { HoỏnV(x[ j ], x[ j +1]); ChSLu = j; } } R = ChSLu; // khụng xột cỏc phn t ó sp cui dóy } while (L < R); return ; } d phc tp ca thut toỏn + Trong trng hp ti nht (dóy cú th t ngc li), ta tớnh c: HVxu = SSxu = n/2 i =1 (n-i) = n(3n 2) 8 + Trong trng hp tt nht (dóy ó c sp): HVtt = n 1 0 = 0 i =1 SStt... Chn tựy ý mt phn t g = xk;(L k R, thng chn k = (L+R)/2)); i = L; j = R; - Bc 2: Tỡm v hoỏn v cỏc cp phn t xi v xj t sai v trớ: - Trong khi (xi < g) i = i + 1; - Trong khi (xj > g) j = j -1; - if (i j) { Hoỏn v xi v xj; i = i + 1; j = j -1; } Tỡm kieỏm vaứ saộp xeỏp trong II.18 - Bc 3: if (i j) Quay lờn bc 2; else Dng; c Ci t thut toỏn void PhõnHoch(mang x, int L, int R) // L, r : ln lt l ch s trỏi... kieỏm vaứ saộp xeỏp trong II.11 44, 55, 12, 42, 94, 18, 06, 67 Vit li dóy di dng ct, ta cú bng cha cỏc kt qu sau mi bc lp: Bc lp 0 44 55 12 42 94 18 06 67 1 44 12 42 55 18 06 67 94 2 12 42 44 18 06 55 67 94 3 4 5 6 12 42 18 06 44 55 67 94 12 18 06 42 44 55 67 94 12 06 18 42 44 55 67 94 06 12 18 42 44 55 67 94 b Ni dung thut toỏn gim s ln so sỏnh tha trong nhng trng hp dóy ó gn c sp trong phng phỏp ni... kieỏm vaứ saộp xeỏp trong } return ; } Vớ d: Vi Heap ban u: 94 67 18 44 55 12 06 42 Ta cú biu din cõy ca dóy sau mi bc lp: 1 42 67 18 2 44 55 12 06 94 67 55 44 18 42 12 06 94 55 44 06 18 42 12 67 94 44 42 06 18 12 55 67 II.23 Tỡm kieỏm vaứ saộp xeỏp trong 94 42 12 06 18 44 55 67 94 18 12 42 06 44 55 67 94 12 06 42 18 44 55 67 94 06 12 42 94 18 44 55 67 II.24 Tỡm kieỏm vaứ saộp xeỏp trong II.25 Duyt cỏc... tng dn bng phng phỏp trn t nhiờn dóy sau: x: 75 55 15 20 85 30 35 10 60 40 50 25 45 80 70 65 Cỏc bc tỏch v trn trong mi bc lp: * Tỏch (ln 1, a nhng ng chy t nhiờn trong dóy x ln lt vo cỏc dóy ph y, z): y: 75 15 20 85 10 60 25 45 80 65 z: 55 30 35 40 50 70 - Trn (trn nhng ng chy t nhiờn tng ng trong cỏc dóy ph y, z thnh cỏc ng chy mi di hn vo dóy x ): x : 55 75 15 20 30 35 40 50 70 85 10 60 25 45 80 65... Bc 2: Trong khi (SCp 1) thc hin: { VTrớCui = 1; i = 1; Trong khi (i < SCp) thc hin: { if (xi > xi+1) { Hoỏn v xi v xi+1; VTrớCui = i; } i = i +1; } SCp = VTrớCui -1; } c Ci t thut toỏn void BubbleSort(mang x, int n) { int ChSCui, SCp = n -1; while (SCp > 0) { ChSCui = 0; for (int i = 0; i< SCp; i++) if (x[i] > x[i+1]) { HoỏnV(x[i], x[i+1]); ChSCui = i; } SCp = ChSCui; } Tỡm kieỏm vaứ saộp xeỏp trong. .. nu khúa khụng quỏ di II.3.10 So sỏnh cỏc phng phỏp sp xp trong Cỏc phng phỏp sp xp trc tip (chn trc tip, ni bt, chốn trc tip), sp xp ShakerSort, núi chung, chỳng u cú phc tp c a thc cp 2: T(n) = O(n2) Tỡm kieỏm vaứ saộp xeỏp trong II.31 Phng phỏp sp xp ShellSort cú phc tp tt hn: T(n) = O(n1,2) Cỏc phng phỏp QuickSort, HeapSort v trn (t nhiờn) trong hu ht trng hp cú phc tp tt hn nhiu: T(n) = O(nlog2n) . Chương II TÌM KIẾM VÀ SẮP XẾP TRONG II.1. Giới thiệu về sắp xếp và tìm kiếm II.1.1. Sắp xếp a. Định nghĩa sắp xếp Cho dãy X gồm n phần tử. nhớ trong hay ngoài mà ta chia các phương pháp sắp xếp thành hai loại: * Sắp xếp trong : Với các phương pháp sắp xếp trong, toàn bộ dữ liệu được đưa vào