1 / 37

Sắp thứ tự

Sắp thứ tự. 1. Phương pháp chèn (Insertion sort). Nội dung phương pháp: Xét dãy a 1 , …., a i-1 có thứ tự, tìm vị trí thích hợp của a i trong dãy trên để chèn vào sao cho ta được dãy a 1 , …., a i có thứ tự. Thực hiện với i = 2, ….., n ta được dãy a 1 , …., a n có thứ tự. Ví dụ.

Download Presentation

Sắp thứ tự

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sắp thứ tự

  2. 1. Phương pháp chèn (Insertion sort) Nội dung phương pháp: • Xét dãy a1, …., ai-1 có thứ tự, tìm vị trí thích hợp của ai trong dãy trên để chèn vào sao cho ta được dãy a1, …., ai có thứ tự. • Thực hiện với i = 2, ….., n ta được dãy a1, …., an có thứ tự

  3. Ví dụ

  4. Giải thuật chèn • Thực hiện với i=2 , …, n: • x = ai • j = i-1 • Khi (j>0) Λ (x<aj) 3. 1 aj+1=aj 3. 2 j = j-1 • aj+1=x

  5. Độ phức tạp • Số phép gán: • Số phép so sánh:

  6. Cài đặt void insertionsort(elem a[], int n, int (*comp)(elem, elem)) { int i, j, sz=sizeof(elem); elem x; for (i=1; i<n; i++) { memcpy(&x, &a[i], sz); j = i-1; while (j>=0 && comp(x, a[j])<0) { memcpy(&a[j+1], &a[j], sz); j--; } memcpy(&a[j+1], &x, sz); } }

  7. 2. Phương pháp chọn (Selection sort) Nội dung phương pháp: • Chọn phần tử nhỏ nhất trong dãy ai, …., an là ak • Hoán đổi phần tử ai với ak. Thực hiện với i = 1, ….., n-1 ta được dãy a1, …., an có thứ tự

  8. Ví dụ

  9. Giải thuật chọn • Với i=1 , …, n-1, thực hiện: • k=i • x = ak • Với j = i+1, …, n, thực hiện: Nếu x>aj • k=j • x=ak • ak = ai • ai=x

  10. Độ phức tạp • Số phép gán: • Số phép so sánh:

  11. Cài đặt void selectionsort(elem a[], int n, int (*comp)(elem, elem)) { int i, j, k, sz=sizeof(elem); elem x; for (i=0; i<n-1; i++) { k = i; memcpy(&x, &a[k], sz); for (j=i+1; j<n; j++) if (comp(x, a[j])>0) { k = j; memcpy(&x, &a[k], sz); } memcpy(&a[k], &a[i], sz); memcpy(&a[i], &x, sz); } }

  12. Cài đặt void selectionsort(elem a[], int n, int (*comp)(elem, elem)) { int i, j, k, sz=sizeof(elem); elem x; for (i=0; i<n-1; i++) { k = i; for (j=i+1; j<n; j++) if (comp(a[k], a[j])>0) k = j; memcpy(&x, &a[k], sz); memcpy(&a[k], &a[i], sz); memcpy(&a[i], &x, sz); } }

  13. 3. Phương pháp đổi chổ Nội dung phương pháp: Duyệt qua dãy, nếu 2 phần tử kề nhau không thứ tự thì hoán đổi Thực hiện cho đến khi dãy có thứ tự Thuật giải nổi bọt (Bubble sort) Phép duyệt: duyệt từ cuối về đầu dãy -> phần tử nhỏ nhất về đầu dãy: nổi bọt

  14. Thuật giải (C) for (i=1; i<n; i++) for (j=n-1; j>=i; j--) if (a[j]<a[j-1]) swap(a[j], a[j-1]); // Phải viết hàm swap(x, y) hoán vị x và y

  15. Sap thu tu - phuong phap noi bot void bubblesort(elem a[], int n, int (*comp)(elem, elem)) { int i, j, sz=sizeof(elem); elem x; for (i=1; i<n; i++) for (j=n-1; j>=i; j--) if (comp(a[j], a[j-1])<0) { memcpy(&x, &a[j], sz); memcpy(&a[j], &a[j-1], sz); memcpy(&a[j-1], &x, sz); } }

  16. Thuật giải BS có sử dụng cờ(C) i=1; do { OK = 1; for (j=n-1; j>=i; j--) if (a[j]<a[j-1]) { swap(a[j], a[j-1]); OK = 0; } i++; } while (!OK);

  17. Thuật giải Sàng (Shaker sort) Nội dung phương pháp: Thực hiện lặp 2 quá trình liên tiếp: Duyệt từ phải qua trái: Nổi bọt Duyệt từ trái qua phải: Lắng đọng Mỗi quá trình ghi nhận vị trí hóa đổi sau cùng làm điểm xuất phát cho quá trình tiếp theo Thực hiện cho đến khi phải vượt trái

  18. l = 1; r = k = n-1; do { for (j=r; j>=l; j--) if (a[j]<a[j-1]) { swap(a[j], a[j-1]); k = j; } l = k+1; for (j=l; j>=r; j++) if (a[j]<a[j-1]) { swap(a[j], a[j-1]); k = j; } r = k-1; } while (l<=r); Thuật giải Shaker sort(C)

  19. II. Các thuật giải kải tiến

  20. 1. Giải thuật “vun đống” (Heap sort) Cải tiến từ phương pháp chọn Định nghĩa: • Heap: Là cấu trúc cây nhị phân đầy đủ theo nghĩa: các nút được bố trí tuần tự từ mức thấp đến mức cao, từ trái qua phải Ví dụ:

  21. 9 6 8 0 3 7 5 2 1 4 Giải thuật “vun đống” (Heap sort) • Heap max (min): Là cấu trúc heap thỏa điều kiện : mọi nút đều có khóa lớn (nhỏ) hơn 2 con Ví dụ:

  22. a1 a2 a3 a4 a5 a6 a7 a1 a3 a2 a6 a7 a4 a5 a8 a9 a10 Tổ chức heap từ dãy • Với dãy a1, a2, ….. an ta tổ chức thành cấu trúc heap như sau: ai có 2 con là a2i và a2i+1 Vẽ lại

  23. a1 a3 a2 a6 a7 a4 a5 a8 a9 a10 Khởi tạo heap max ban đầu • Ta có ai với i=n/2+1, … n là các nút lá trên cây nên hiển nhiên thỏa mãn tính chất heap max • Để khởi tạo heap max ban đầu ta tìm cách biến đổi ai (với i=n/2, …, 1) thành heap max khi ai+1, …, an thỏa heap max

  24. Sắp thứ tự • Khi i=1 ta có dãy thỏa mãn tính chất heap max, nghĩa là a1 là phần tử lớn nhất • Để sắp thứ tự, phần tử lớn nhất phải nằm cuối nên ta hoán đổi phần tử a1 với an • Biến đổia1 thành heap max khi a2, …, an-1 thỏa heap max • Tiếp tục hoán đổi và biến đổi cho đến khi dãy có thứ tự

  25. 4 9 7 7 9 8 1 1 0 0 6 6 8 4 5 5 2 2 3 3 Giải thuật biến đổi heap max (q, r) 4

  26. 9 3 7 7 8 8 1 1 0 0 6 6 4 4 5 5 2 2 3 9 3

  27. 8 2 7 7 6 6 1 1 0 0 5 5 4 4 3 3 2 8 9 9

  28. 2 7 7 2 6 6 1 1 0 0 5 5 4 4 3 3 8 8 9 9 2

  29. 3 2 6 1 0 5 4 7 8 9 • Tiếp tục thực hiện cho đến khi dãy có thứ tự

  30. Giải thuật biến đổi heap max (q, r) • Khởi tạo • x = aq • i=q • j=2i • cont=true • Khi (j<=r) Λ cont, thực hiện: 2.1 Nếu (j<r) Λ (aj<aj+1) thì j=j+1 2.2 Nếu x<aj thì • ai = aj • i=j • j=2i 2.3 Ngược lại • cont = False • ai=x

  31. Sắp thứ tự • Khởi tạo heap max ban đầu Với i=n/2, …, 1. Thực hiện: Biến đổi heap max(i, n) • Sắp thứ tự • i=n • Lặp • Hoán đổi a1 với ai • i = i-1 • Biến đổi heap max(1, i) • Cho đến khi i=1

  32. void sift(elem a[ ], int q, int r, int (*comp)(elem, elem)) { elem x; int i, j, cont =1, sz = sizeof(elem); i = q; j = 2*i+1; //lưu ý memcpy(&x, &a[i], sz); while (j<=r && cont) { if (j<r && comp(a[j], a[j+1])<0) j++; if (comp(x, a[j]) <0) { memcpy(&a[i], &a[j], sz); i = j; j = 2*i+1; //lưu ý } else cont = 0; } memcpy(&a[i], &x, sz); }

  33. Hàm Heapsort void heapsort(elem a[ ], int n, int (*comp)(elem, elem)) { int i, sz = sizeof(elem); elem x; for (i=n/2-1; i>=0; i--) //lưu ý n/2-1 và 0 sift(a, i, n-1, comp); i = n-1; do { memcpy(&x, &a[0], sz); //lưu ý a[0] memcpy(&a[0], &a[i], sz); memcpy(&a[i], &x, sz); i--; sift(a, 0, i, comp); //0 } while (i>0); }

  34. 2. Giải thuật Quick sort • Cải tiến từ phương pháp đổi chổ • Dựa trên phép phân hoạch: • Chọn giá trị phân hoạch x thỏa: Min { ai } ≤ x ≤ Max { ai } • Dò tìm từ trái (l) qua phải phần tử ai≥ x • Dò tìm từ phải (r) qua trái phần tử aj≤x • Nếu i < j thì hoán đổi ai với aj • Tiếp tục thực hiện cho đến khi i>j Kết quả dãy sẽ bị phân hoạch thành 2 dãy: Dãy từ l đến j mang giá trị ≤ x Dãy từ i đến r mang giá trị ≥ x • Để sắp thứ tự ta tiếp tục phân hoạch trên 2 đoạn (l,j) và (i, r)

  35. void sort(elem a[ ], int l, int r, int (*comp)(elem, elem)) { static elem x, t; int i, j, sz = sizeof(elem); i = l; j = r; memcpy(&x, &a[(l+r)/2], sz); do { while (comp(a[i], x)<0) i++; while (comp(a[j], x)>0) j--; if (i<=j) { memcpy(&t, &a[i], sz); memcpy(&a[i], &a[j], sz); memcpy(&a[j], &t, sz); i++; j--; } } while (i<=j); if (l<j) sort(a, l, j, comp); if (i<r) sort(a, i, r, comp); }

  36. void qsort(elem a[ ], int n, int (*comp)(elem, elem)) { sort(a, 0, n-1, comp); }

  37. Bài tập • Viết • Quick sort 1 lời gọi đệ quy • Quick sort không đệ quy • Chương trình nhập 1 dãy số nguyên, đưa: • Lẻ về đầu dãy và sắp thứ tự tăng • Chẵn về cuối dãy và sắp thứ tự giảm

More Related