Bài giảng môn Cấu trúc dữ liệu chương 3 : Kỹ thuật sắp xếp

2.1. a. Bubble Sort (tt) Phân tích thuật toán: Trong mọi trường hợp Số phép gán G = 0 Số phép so sánh S = (N-1) + (N-2) + + 1 = ½N(N-1) Trong trường hợp tốt nhất Số phép hoán vị các phần tử Hmin = 0 Trong trường hợp xấu nhất Số phép hoán vị các phần tử Hmax = (N-1) + (N-2) + + 1

ppt31 trang | Chia sẻ: haohao89 | Lượt xem: 2661 | Lượt tải: 2download
Bạn đang xem trước 20 trang tài liệu Bài giảng môn Cấu trúc dữ liệu chương 3 : Kỹ thuật sắp xếp, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Môn: CẤU TRÚC DỮ LIỆU Chương 3: KỸ THUẬT SẮP XẾP NỘI DUNG CHƯƠNG 3 Khái quát về sắp xếp Các phương pháp sắp xếp (Sắp xếp trên dãy) Sắp xếp bằng phương pháp đổi chỗ (Exchange) Sắp xếp bằng phương pháp chọn (Selection) Sắp xếp bằng phương pháp chèn (Insertion) Sắp xếp bằng phương pháp trộn (Merge) Các phương pháp sắp xếp (Sắp xếp trên tập tin) Sắp xếp tập tin bằng phương pháp trộn Sắp xếp tập tin theo chỉ mục BÀI TẬP 1. Khái quát về sắp xếp Sắp xếp là thao tác cần thiết thường được thực hiện trong quá trình lưu trữ và quản lý dữ liệu. Thứ tự dữ liệu có thể tăng hay giảm, tăng hay giảm thuật toán sắp xếp là tương tự. Hai nhóm giải thuật sắp xếp Các giải thuật sắp xếp thứ tự nội (sx thứ tự trên mảng) Các giải thuật sắp xếp thứ tự ngoại (sx thứ tự trên tập tin) Xem như mỗi phần tử dữ liệu được xem xét có một thành phần khóa (Key) để nhận diện có kiểu dữ liệu T, các thành phần còn lại là thông tin (Info), như vậy mỗi phần tử có cấu trúc như sau: typedef struct DataElement { T Key; InfoData Info; } DataType; Để đơn giản, quan tâm thành phần dữ liệu chỉ là khóa nhận diện 2. Sắp xếp trên dãy/mảng 2.1. Sắp xếp bằng phương pháp đổi chỗ (Exchange) a. Thuật toán sắp xếp nổi bọt (Bubble Sort) b. Thuật toán sắp xếp dựa trên phân hoạch (Partitioning Sort) (thuật toán sx nhanh Quick Sort) 2.2. Sắp xếp bằng phương pháp chọn (Selection Sort) Chọn trực tiếp (Straight Selection Sort) 2.3. Sắp xếp bằng phương pháp chèn (Insertion Sort) Chèn trực tiếp (Straight Insertion Sort) 2.4. Sắp xếp bằng phương pháp trộn (Merge Sort) a. Trộn trực tiếp (Straight Merge Sort) b. Trộn tự nhiên (Natural Merge Sort) 2. Sắp xếp trên dãy/mảng (tt) 2.1. a. Thuật toán sắp xếp nổi bọt (Bubble Sort) Ý tưởng: Đi từ cuối mảng đến đầu mảng, nếu phần tử ở dưới I; J--) if (M[J] = Last) // mảng con chỉ còn không quá 1 phần tử Thực hiện BKT B4: X = M[(First + Last)/2] B5: I = First // Từ dãy con số 1 tìm phần tử có giá trị lớn hơn X B6: IF (M[I] > X) Thực hiện B8 B7: ELSE I++ Lặp lại B6 B8: J = Last // Xuất phát từ cuối dãy 3 để tìm phần tử có giá trị nhỏ hơn X B9: IF (M[J] =Last) return; T X = M[(First + Last)/2]; int I = First; int J = Last; do { while (M[I] X) J-- if (I N) Thực hiện B8 B7: ELSE IF (Min >M[Postion]) Min = M[Position] PositionMin = Pos Position ++ Lặp lại B6 kiểm tra vị trí so với N B8: Hoán vị (M[K+1], M[PositionMin]) B9: K++ B10: Lặp lại B2 BKT: Kết thúc 2. Sắp xếp trên dãy/mảng (tt) 2.2. (tt) Straight Selection Sort: Cài đặt thuật toán void StraightSelectionSort(T M[], int N) { int K = 0; int PositionMin; while (KM[Position]) { Min = M[Position]; PositionMin = Position; } } Swap (M[K], M[PositionMin]); K++; } return; } 2. Sắp xếp trên dãy/mảng (tt) 2.2. (tt) Chọn trực tiếp (Straight Selection Sort) Phân tích thuật toán: Trong mọi trường hợp Số phép so sánh S = (N-1) + (N-2) +… + 1 = ½N(N-1) Số phép hoán vị H = N-1 Trong trường hợp tốt nhất Số phép gán Gmin = 2 x (N-1) Trong trường hợp xấu nhất Số phép gán Gmax = 2 x [(N-1) + (N-2) +… + 1] Trong trường hợp trung bình Số phép gán Gavg = (Gmin+Gmax)/2 2. Sắp xếp trên dãy/mảng (tt) 2.3. Sắp xếp bằng phương pháp chèn (Insertion Sort) Chèn trực tiếp (Straight Insertion Sort) Để chèn phần tử thứ K+1 vào K phần tử đầu dãy đã có thứ tự  tiến hành tìm đúng của phần tử K+1 trong K phần tử đầu bằng giải thuật tìm kiếm tuần tự. Khi tìm được vị trí chèn, dời các phần tử từ vị trí chèn đến phần tử thứ K sang phải 1 vị trí 2. Sắp xếp trên dãy/mảng (tt) 2.3. (tt) Thuật Toán Chèn trực tiếp (Straight Insertion Sort) B1: K=0 B2: IF (K = N) Thực hiện BKT B3: X = M[K+1] B4: Position = 1 B5: IF(Position > K) Thực hiện B7 B6: ELSE B61: IF (X Position) B81: M[I] = M[I-1] B82: I -- B83: Lặp lại B8 B9: ELSE B91: M[Position] = X B92: K++ B93: Lặp lại B2 BKT: Kết thúc 2. Sắp xếp trên dãy/mảng (tt) 2.3. (tt) Cài đặt Thuật Toán Chèn trực tiếp (Straight Insertion Sort) void StraightInsertionSort(T M[], int N) { int K = 1; int Position; while (KM[Position]) Position ++; for (int I = K; I > Position; I--) M[I] = [I-1]; M[Position] = X; K++ } return; } 2. Sắp xếp trên dãy/mảng (tt) 2.3. Chèn trực tiếp (Straight Insertion Sort) (tt) Phân tích thuật toán Trong trường hợp tốt nhất Số phép gán Gmin = 2 × (N-1) Số phép so sánh Smin = 1 + 2 + … +(N-1) = N ×(N-1)/2 Số phép hoán vị Hmin = 0 Trong trường hợp xấu nhất Số phép gán Gmax = [2 × (N-1)] + [1+2+…+(N-1)] Số phép so sánh Smax = (N-1) Số phép hoán vị Hmax = 0 Trong trường hợp trung bình Số phép gán Gavg = (Gmin+Gmax)/2 Quá trình tìm vị trí chèn của phần tử thứ K+1 và quá trình dời 2. Sắp xếp trên dãy/mảng (tt) 2.4. Phương pháp sắp xếp Trộn (Merge Sort) Các thuật toán trộn tìm cách tách các mảng con theo các đường chạy (run) rồi tiến hành nhập các mảng theo từng cặp để tạo thành các đường mới có chiều dài lớn hơn đường chạy cũ. Sau một số lần tách nhập, cuối cùng mảng M chỉ còn 1 đường chạy đuợc sắp xếp thứ tự. Đường chạy (run): Dãy M[I], M[I+1],…M[J] (I>=1, I<=J, J<=N) là một đường chạy nếu nó có thứ tự Chiều dài của đường chạy (run’s length): Là số phần tử của một đường chạy. Một dãy sẽ bao gồm nhiều đường chạy. Trộn các đường chạy: Khi trộn các đường chạy với nhau sẽ tạo ra đường chạy mới có tổng chiều dài bằng các đường chạy ban đầu. 2. Sắp xếp trên dãy/mảng (tt) 2.4. a. Trộn trực tiếp (Straight Merge Sort) Dãy M có N đường chạy (runs) với chiều dài L=1, tiến hành phân phối luân phiên N runs của dãy về 2 dãy phụ T1, T2 (N/2 runs) Trộn từng cặp các dãy phụ T1, T2 thành 1 run có chiều dài là L=2 đưa trở về dãy M, (lúc này M gồm N/2 runs) với chiều dài mỗi run là L =2 Sau mỗi lần phân phối, số run trên M giảm đi ½ và chiều dài mỗi run tăng gấp đôi. Sau log2N lần phân phối và trộn thì dãy M chỉ còn lại 1 run với chiều dài được sắp xếp  dãy M có thứ tự. Thuật giải chia làm 2 phần Thuật giải phân phối các đường chạy L trên M về 2 dãy phụ T1 & T2 Thuật giải trộn các cặp đường chạy trên T1 & T2 có chiều dài L về M thành các đường chạy với chiều dài 2*L 2. Sắp xếp trên dãy/mảng (tt) 2.4. a. (tt) Phân tích thuật toán Straight Merge Sort Thực hiện log2N lần phân phối và trộn các run Mỗi lần phân phối thực hiện N phép gán, 2N phép so sánh Mỗi lần trộn N phép gán, 2N+N/2 phép so sánh Số phép hoán vị cho mọi trường hợp: H = 0 Thuật giải dùng 2 dãy phụ, tổng số phần tử trong 2 dãy phụ = N  lãng phí bộ nhớ  cải tiến dùng 1 dãy phụ và kết hợp quá trình trộn và phân phối luân phiên về 2 dãy. Sau đó đổi vai trò 2 dãy này với nhau 2. Sắp xếp trên dãy/mảng (tt) 2.4. b. Trộn tự nhiên (Natural Merge Sort) Tận dụng đường chạy tự nhiên trên dãy, tiến hành trộn tương ứng các cặp đường chạy tự nhiên nằm 2 đầu của dãy thành 1 đường chạy mới và phân phối luân phiên các đường chạy mới này về 2 đầu dãy phụ T. Từ dãy phụ T, tiếp tục trộn cặp tương ứng ở 2 đầu tạo thành 1 run mới và phân phối luân phiên run mới này về 2 đầu dãy M.  Tiếp tục quá trình cho đến khi M hay T chỉ còn lại 1 run 2. Sắp xếp trên dãy/mảng (tt) 2.4. b. Phân tích giải thuật Natural Merge Sort Trong trường hợp tốt nhất Số phép gán Gmin = 1 Số phép so sánh Smin = 2N(N-1) Số phép hoán vị Hmin = 0 Trong trường hợp xấu nhất Số phép gán Gmax = N × Log2N + 1 Số phép so sánh Smax = 2N × Log2N + 2 Số phép hoán vị Hmax = 0 Trong trường hợp trung bình Số phép gán Gavg = (Gmin+Gmax)/2 3. Sắp xếp trên tập tin 1. Sắp xếp trong file bằng phương pháp trộn a. Trộn trực tiếp (Straight Merge Sort) b. Trộn tự nhiên (Natural Merge Sort) 2. Sắp xếp theo chỉ mục 3. Sắp xếp trên tập tin (tt) 1. a. Trộn trực tiếp (File Straight Merge Sort) Tương tự trộn trực tiếp trên mảng Ban đầu tập tin Fd có N runs chiều dài mỗi run là L=1, tiến hành phân phối luân phiên các runs của Fd về K tập tin phụ Ft1, Ft2, … FtK, mỗi tập tin có N/K runs. Trộn tương ứng từng bộ K runs ở K tập tin phụ Ft1, Ft2, … FtK thành 1 run mới có chiều dài L=K để đưa về tập tin Fd, tập tin Fd lúc này có N/K runs với chiều dài mỗi run L= K. Sau mỗi lần phân phối và trộn các run trên Fd  số các run giảm K lần, và tương ứng chiều dài mỗi run trên Fd sẽ tăng K lần. Sau Log2N lần phân phối và trộn  Fd chỉ còn lại 1 rund với chiều dài N  dữ liệu tập tin Fd có thứ tự Thuật giải chia làm 2 phần Thuật giải phân phối các đường chạy L trên Fd về 2 dãy phụ Ft1 & Ft2 Thuật giải trộn các cặp đường chạy trên Ft1 & Ft2 có chiều dài L về Fd thành các đường chạy với chiều dài 2*L 3. Sắp xếp trên tập tin (tt) 1. b. Trộn tự nhiên (Natural Merge Sort) 3. Sắp xếp trên tập tin (tt) 2. Sắp xếp theo chỉ mục BÀI TẬP Bài tập chương 3 (trang 84 - 85) (Lý thuyết) Cho một mảng số nguyên bao gồm 20 phần tử như sau 23 34 46 16 8 9 7 6 13 22 65 45 18 29 45 15 3 10 84 21 Tính số phép gán, số lần so sánh, hoán vị của mỗi thuật toán (Bubble Sort, QuickSort, Straight Selection Sort, Straight Insertion Sort , Straight Merge Sort, Natural Merge Sort) là bao nhiêu? (Lý thuyết) Nếu đối với dãy có giá trị phần tử giữa dãy lớn nhất, áp dụng phương pháp nào nhanh hơn QuickSort hay Bubble Sort? (VD: dãy : 23 4 6 77 45 5 6 7) Cài đặt các giải thuật sắp xếp trong lý thuyết đối với các dãy | mảng có giá trị giảm dần