Đổi chỗ trực tiếp – Interchange Sort... Đổi chỗ trực tiếp – Interchange Sort... Đổi chỗ trực tiếp – Interchange Sort... Đổi chỗ trực tiếp – Interchange Sort... Danh sách liên kết đơnMô t
Trang 1Đại Học Sư Phạm Tp Hồ Chí Minh
Phần: CẤU TRÚC DỮ LIỆU
ÔN TỐT NGHIỆP
Trang 2x p,…)ế– Ứng d ng c a DSLK: Stack và Queue.ụ ủ
Trang 3• Các gi i thu t s p x p ả ậ ắ ế
– S p x p đ i ch tr c ti p ắ ế ổ ỗ ự ế – S p x p ch n tr c ti p ắ ế ọ ự ế – S p x p chèn tr c ti p ắ ế ự ế – S p x p n i b t ắ ế ổ ọ
– S p x p n i b t c i ti n ắ ế ổ ọ ả ế – Shell sort
– Heap sort
Trang 4• Biểu diễn giải thuật bằng mã giả
• Biểu diễn giải thuật bằng sơ đồ khối
– Cài đ t b ng ngôn ng C/C++ ặ ằ ữ
Trang 8Giải thuật tìm kiếm tuyến tính
Lần lặp i a[i] = x? Kết quả
1 0 a[0] = 4 ≠ x = 3 i = i + 1 = 1
2 1 a[1] = 1 ≠ x = 3 i = i + 1 = 2
3 2 a[2] = 6 ≠ x = 3 i = i + 1 = 3
Trang 9Giải thuật tìm kiếm nhị phân
Trang 11Giải thuật tìm kiếm nhị phân
B c 1: ướ left = 0; right = N-1; //tìm trên t t c các ph n t ấ ả ầ ử
B c 2: mid = (left + right)/2 ướ ; //l y m c đ so sánh ấ ố ể
So sánh a[mid] v i x có 3 kh n ng ớ ả ă
- x=a[mid] : tìm th y D ng ấ ừ
- x<a[mid] : left = mid +1 ; //tìm ti p trong dãy a ế left …a mid-1
- x>a[mid] : right = mid -1 ; //tìm ti p trong dãy a ế mid+1 …a right
B c 3: ướ N u left <= right Quay l i b c 2 ế ạ ướ
Trang 12Giải thuật tìm kiếm nhị phân
B c 1: ướ left = 0; right = N-1; //tìm trên t t c các ph n t ấ ả ầ ử
B c 2: mid = (left + right)/2 ướ ; //l y m c đ so sánh ấ ố ể
So sánh a[mid] v i x có 3 kh n ng ớ ả ă
- x=a[mid] : tìm th y D ng ấ ừ
- x<a[mid] : right = mid -1 ; //tìm ti p trong dãy a ế left …a mid-1
- x>a[mid] : left= mid +1 ; //tìm ti p trong dãy a ế mid+1 …a right
Trang 13int mid = (left + right)/2;
if (x == a[mid]) return mid;
if (x < a[mid]) right = mid - 1;
if (x > a[mid]) left = mid + 1;
}
return -1;
Trang 14Giải thuật tìm kiếm nhị phân
Lần lặp L R m=[(L+R)/2] a[i] = x? Kết quả
1 0 6 [(0+6)/2] = 3 a[3] = 6 ≠ x = 3 R = m-1 = 2
2 0 2 [(0+2)/2] = 1 a[1] = 3 ≠ x = 3 Kết thúc gt
Trang 15– S p x p chèn tr c ti p ắ ế ự ế – Insertion Sort – S p x p n i b t ắ ế ổ ọ – Buble Sort
– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort – Quick sort – Merge sort
Trang 17• Hai thao tác c b n ơ ả
– So sánh – Gán
Trang 18– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort – Quick sort – Merge sort
Trang 19• M ng ch a s p x p s có ngh ch th ả ư ắ ế ẽ ị ế
• M ng đã có th t s không ch a ngh ch th ả ứ ự ẽ ứ ị ế
Trang 20Đổi chỗ trực tiếp – Interchange Sort
• Tìm t t c ngh ch th , tri t tiêu chúng b ng cách hoán v 2 ph n ấ ả ị ế ệ ằ ị ầ
t t ng ng trong ngh ch th ử ươ ứ ị ế
Trang 22Đổi chỗ trực tiếp – Interchange Sort
• Cho dãy số a:
Trang 23Đổi chỗ trực tiếp – Interchange Sort
Trang 24Đổi chỗ trực tiếp – Interchange Sort
Trang 25Đổi chỗ trực tiếp – Interchange Sort
Trang 26Đổi chỗ trực tiếp – Interchange Sort
Trang 27Đổi chỗ trực tiếp – Interchange Sort
Trang 28Interchange Sort - Kết quả
Trang 29Đổi chỗ trực tiếp – Interchange Sort
void InterchangeSort(int a[], int N ) {
Trang 30– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort – Quick sort – Merge sort
Trang 31• Đư a ph n t này v v trí đúng là đ u dãy hi n hành ầ ử ề ị ầ ệ
• Xem dãy hi n hành ch còn N-1 ph n t c a dãy ban ệ ỉ ầ ử ủ
đ u ầ
– B t đ u t v trí th 2; ắ ầ ừ ị ứ – L p l i quá trình trên cho dãy hi n hành đ n khi dãy hi n ặ ạ ệ ế ệ hành ch còn 1 ph n t ỉ ầ ử
Trang 33Chọn trực tiếp – Selection Sort
• Cho dãy số a:
Trang 34Chọn trực tiếp – Selection Sort
Trang 35Chọn trực tiếp – Selection Sort
Trang 36Chọn trực tiếp – Selection Sort
Trang 37Selection sort
void SelectionSort ( int a[], int N )
{
int min; // chỉ số phần tử nhỏ nhất trong dãy hiện hành
for ( int i=0; i<N-1 ; i++) {
}
Trang 38– S p x p chèn tr c ti p ắ ế ự ế – Insertion Sort
– S p x p n i b t ắ ế ổ ọ – Buble Sort – S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort – Quick sort – Merge sort
Trang 39Chèn trực tiếp – Insertion Sort
• Gi s có m t dãy a ả ử ộ 1 , a2 , ,an trong đó i ph n t đ u tiên a ầ ử ầ 1 , a2, ,ai-1 đã có th t ứ ự
• Tìm cách chèn ph n t a ầ ử i vào v trí thích h p ị ợ c a đo n đã đ c ủ ạ ượ
s p đ có dãy m i a ắ ể ớ 1 , a2 , ,ai tr nên có th t V trí này chính ở ứ ự ị
là v trí gi a hai ph n t a ị ữ ầ ử k-1 và ak th a a ỏ k-1 < ai < ak (1≤k≤i)
Trang 40Chèn trực tiếp – Insertion Sort
• B c 1 ướ : i = 2; // gi s có o n a[1] ã ả ử đ ạ đ đượ ắ c s p
• B c 2 ướ : x = a[i]; Tìm v trí pos thích h p trong đo n ị ợ ạ a[1] đ n a[i-1] đ chèn a[i] vào ế ể
• B c 3 ướ : D i ch các ph n t t a[pos] đ n ờ ỗ ầ ử ừ ế a[i-1] sang ph i 1 v trí đ dành ch cho a[i] ả ị ể ổ
• B c 4 ướ : a[pos] = x; // có o n a[1] a[i] ã đ ạ đ đượ ắ c s p
• B c 5 ướ : i = i+1;
N u i < n : L p l i B c 2 ế ặ ạ ướ
Trang 41Chèn trực tiếp – Insertion Sort
• Cho dãy số :
Trang 42Chèn trực tiếp – Insertion Sort
Trang 43Chèn trực tiếp – Insertion Sort
Trang 44Insertion Sort – Cài đặt
void InsertionSort ( int a[], int N )
{
int pos, i;
int x;//lưu trữ a[i] tránh bị ghi đè khi dời chỗ các phần tử.
for (i=1 ; i<N ; i++) //đoạn a[0] đã sắp
{
x = a[i];
for (pos=i;(pos>0)&&(a[pos-1]>x);pos ) a[pos] = a[pos-1];
a[pos] = x;// chèn x vào dãy
Trang 45Insertion Sort - Kết quả
Trang 461.2 Sắp xếp
• Các giải thuật sắp xếp
– Sắp xếp đổi chỗ trực tiếp - Interchange Sort
– Sắp xếp chọn trực tiếp – Selection Sort
– Sắp xếp chèn trực tiếp – Insertion Sort
– Sắp xếp nổi bọt – Bubble Sort
– Sắp xếp nổi bọt cải tiến - Shaker Sort
– Shell sort
– Heap sort
– Quick sort
– Merge sort
Trang 47Nổi bọt – Bubble Sort
• Ý t ng chính c a gi i thu t là xu t phát t cu i dãy, đ i ch ưở ủ ả ậ ấ ừ ố ổ ỗ các c p ph n t k c n đ đ a ph n t nh h n trong c p ặ ầ ử ế ậ ể ư ầ ử ỏ ơ ặ
ph n t đó v v trí đúng đ u dãy hi n hành, sau đó s không xét ầ ử ề ị ầ ệ ẽ
đ n nó b c ti p theo, do v y l n x lý th i s có v trí ế ở ướ ế ậ ở ầ ử ứ ẽ ị
đ u dãy là i ầ
Trang 48Nổi bọt – Bubble Sort
• Bước 1 : i = 1; // lần xử lý đầu tiên
• Bước 2 : j = N; //Duyệt từ cuối dãy ngược về vị trí i
Trong khi (j > i) thực hiện:
Trang 49Nổi bọt – Bubble Sort
• Cho dãy số a:
Trang 50Nổi bọt – Bubble Sort
Trang 51Nổi bọt – Bubble Sort
Trang 52Nổi bọt – Bubble Sort
Trang 53Nổi bọt – Bubble Sort
Trang 54Bubble sort - Cài đặt
void BubbleSort ( int a[], int N)
Trang 55Bubble Sort - Kết quả
Trang 56– S p x p chèn tr c ti p ắ ế ự ế – Insertion Sort – S p x p n i b t ắ ế ổ ọ – Buble Sort
– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort – Quick sort – Merge sort
Trang 57• D a trên nguyên t c đ i ch tr c ti p ự ắ ổ ỗ ự ế Kh c ph c nh ắ ụ ượ c
đi m c a Bubble Sort ể ủ
• Trong m i l n s p x p, duy t m ng theo 2 l t t 2 phiá ỗ ầ ắ ế ệ ả ượ ừ khác nhau :
– L t đi: đ y ph n t nh v đ u ượ ẩ ầ ử ỏ ề ầ
m ng ả – L t v : đ y ph n t l n v cu i ượ ề ẩ ầ ử ớ ề ố
m ng ả
• Ghi nh n l i nh ng đo n đã s p x p nh m ti t ki m các phép ậ ạ ữ ạ ắ ế ằ ế ệ
Trang 58Shaker Sort
void ShakeSort(int data[], int n){
int i, j, left, right, k;
Trang 59– S p x p chèn tr c ti p ắ ế ự ế – Insertion Sort – S p x p n i b t ắ ế ổ ọ – Buble Sort
– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort
– Heap sort
– Quick sort – Merge sort
Trang 60với ∀i ∈ [left, right]
–Khi đó (ai , a2i), (ai ,a2i+1) được gọi là các cặp phần tử liên đới.
–Heap được định nghĩa như trên được dùng trong trường hợp sắp xếp tăng dần, khi sắp xếp giảm
Trang 63Sắp xếp cây - Heap sort
• Một số tính chất của Heap:
–Tính chất 1: Nếu aleft, aleft+1, …, aright là một heap thì khi cắt bỏ một số phần tử ở hai đầu của heap, dãy con còn lại vẫn là một heap.
–Tính chất 2: Nếu a1, a2, …, an là một heap thì phần tử a1 (đầu heap) luôn là phần tử lớn nhất trong heap.
–Tính chất 3: Mọi dãy con aleft, aleft+1, , arightthỏa: 2left > right đều là heap.
Trang 64Sắp xếp cây - Heap sort
• Sắp xếp dãy tăng dần qua 2 giai đoạn:
–Giai đoạn 1: hiệu chỉnh dãy ban đầu thành heap
–Giai đoạn 2: sắp xếp heap có được sau giai đoạn 1 thành dãy tăng dần
Trang 65Heap sort – Giai đoạn 1
//input: dãy (a, N) //output: dãy (a, N) là một heap
• Bước 1: left = N/2; //Thêm các phần tử aleft, , a1 vào heap
• Bước 2: Trong khi left > 0
//Lưu ý: đoạn aleft+1, …, aN đã là heap
• Bước 21: Hiệu chỉnh đoạn aleft, …, aN thành heap
• Bước 22: left = left - 1;
//Hết lặp
Trang 66Tạo heap
• n = 8, n/2 = 4
• Xuất phát từ a[4], so sánh với a[8] đổi chổ
• a[3] so sánh với a[6], a[7]
• a[2] so sánh với a[4], a[5] a[2] ↔ a[4]
Trang 67Heap sort – Giai đoạn 2
• Vấn đề: Sắp xếp heap a1, …, aN thành dãy tăng dần
//Đặt: right = N dãy a1, …, aright là heap.
• Ý tưởng:
– Theo tính chất 2: a1 sẽ là phần tử lớn nhất, vì vậy vị trí đúng của a1 phải là right - cuối dãy.
Đổi chổ (a1, aright) được thêm một phần tử ở đúng vị trí
Theo tính chất 3: dãy con a2, …, aright-1 vẫn là heap
Giảm right, thêm a1 vào dãy và hiệu chỉnh lại
dãy a1, …, aright là heap.
Trang 68Heap sort – Giai đoạn 2
//input: dãy (a, N) là heap //output: dãy (a, N) sắp tăng dần
• Bước 1: right = N; //Bắt đầu thực hiện từ cuối dãy
• Bước 2: Trong khi right > 1
//Đưa phần tử lớn nhất (a1)về vị trí right
• Bước 2.1: Hoánvị (a1 , aright);
//Loại bỏ phần tử lớn nhất ra khỏi heap
• Bước 2.2: right := right -1;
• Bước 2.3: Hiệu chỉnh đoạn a , a , …, a thành heap
Trang 69Hiệu chỉnh heap
• Đỗi chổ a[1] ↔ a[8] có 1 phần tử đã đúng vị trí
• Tiến hành tương tự cho dãy n-1 phần tử
Trang 70– S p x p chèn tr c ti p ắ ế ự ế – Insertion Sort – S p x p n i b t ắ ế ổ ọ – Buble Sort
– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort
– Quick sort
– Merge sort
Trang 71Quick sort – Ý tưởng
• Giải thuật QuickSort sắp xếp dãy a1, a2 , aN dựa trên việc phân hoạch dãy ban đầu thành 3 phần :
–Phần 1: Gồm các phần tử có giá trị không lớn hơn x
–Phần 2: Gồm các phần tử có giá trị bằng x
–Phần 3: Gồm các phần tử có giá trị không bé hơn x
Trang 72Quick sort – Ý tưởng
• Sau khi thực hiện phân hoạch, dãy ban đầu được phân thành 3 đoạn:
–1 a k < x , với k = 1 j –2 a k = x , với k = j+1 i-1 –3 a k > x , với k = i N
Trang 73• Đoạn thứ 2 đã có thứ tự
• Nếu các đoạn 1 và 3 chỉ có 1 phần tử: đã có thứ tự
khi đó dãy con ban đầu đã được sắp
Quick sort – Ý tưởng
Trang 74• Đoạn thứ 2 đã có thứ tự
• Nếu các đoạn 1 và 3 có nhiều hơn 1 phần tử thì dãy ban
đầu chỉ có thứ tự khi các đoạn 1, 3 được sắp
• Để sắp xếp các đoạn 1 và 3, ta lần lượt tiến hành việc
phân hoạch từng dãy con theo cùng phương pháp phân hoạch dãy ban đầu vừa trình bày …
Quick sort – Ý tưởng
Trang 75Quick sort – Giải thuật
• Bước 1: Nếu left ≤ right //dãy có ít hơn 2 phần tử
Kết thúc; //dãy đã được sắp xếp
• Bước 2: Phân hoạch dãy aleft … aright thành các đoạn: aleft aj,
aj+1 ai-1, ai Aright
Đoạn 1 ≤ x Đoạn 2: aj+1 ai-1 = x Đoạn 3: ai aright ≥ x
• Bước 3: Sắp xếp đoạn 1: aleft aj
• Bước 4: Sắp xếp đoạn 3: ai aright
Trang 76Quick sort – Phân hoạch dãy
//input: dãy con aleft, …, aright
//output: dãy con chia thành 3 đoạn: đoạn 1 ≤ đoạn 2 ≤ đoạn 3
• Bước 1: Chọn tùy ý một phần tử a[p] trong dãy con là giá trị
mốc:
x = a[p];
• Bước 2: Duyệt từ 2 đầu dãy để phát hiện và hiệu chỉnh cặp
phần tử a[i], a[j] vi phạm điều kiện
– Bước 21: i = left; j = right;
– Bước 22: Trong khi (a[i]<x) i++;
– Bước 23: Trong khi (a[j]>x) j ;
– Bước 24: Nếu i<= j // a[i] ≥ x ≥ a[j] mà a[j] đứng sau a[i]
Trang 78Quick sort – Ví dụ
Trang 79Quick sort – Ví dụ
• Phân hoạch đoạn l =1, r = 3:
x = A[2] = 2
Trang 80Quick sort – Ví dụ
• Phân hoạch đoạn l = 5, r = 8:
x = A[6] = 6
Trang 81• Phân hoạch đoạn l = 7, r = 8:
x = A[7] = 6
Trang 82Quick sort – Cài đặt
void QuickSort ( int a[], int left, int right)
{
int i, j, x;
if (left ≥ right) return ;
x = a[(left+right)/2]; // chọn phần tử giữa làm giá trị mốc
Trang 83– S p x p chèn tr c ti p ắ ế ự ế – Insertion Sort – S p x p n i b t ắ ế ổ ọ – Buble Sort
– S p x p n i b t c i ti n ắ ế ổ ọ ả ế - Shaker Sort
– Shell sort – Heap sort – Quick sort
– Merge sort
Trang 84Merge sort – Ý tưởng
• Giải thuật Merge sort sắp xếp dãy a1, a2, , an dựa trên nhận xét sau:
–Mỗi dãy a 1 , a 2 , , a n bất kỳ là một tập hợp các dãy con liên tiếp mà mỗi dãy con đều đã có thứ tự
• Ví dụ: dãy 12, 2, 8, 5, 1, 6, 4, 15 có thể coi như gồm 5 dãy con không giảm (12); (2, 8); (5); (1, 6); (4, 15).
–Dãy đã có thứ tự coi như có 1 dãy con.
Trang 85– Bước 21: Phân phối đều luân phiên dãy a1, a2, …, anthành 2 dãy b, c theo từng nhóm k phần tử liên tiếp nhau.
– Bước 22: Trộn từng cặp dãy con gồm k phần tử của
2 dãy b, c vào a
Trang 862 8 5 1 6 4 15 12
1 Merge sort – Ví dụ
Trang 872 8 5 1 6 4 15 12
1 Merge sort – Ví dụ
Trang 888 1 4 12
1 Merge sort – Ví dụ
Trang 898 5
1 6
4 15 12
1 Merge sort – Ví dụ
Trang 9012 5 8 1 6 4 15 2
1 Merge sort – Ví dụ
k = 2; Phân phối đều luân phiên
Trang 9112 8
1 4
6 15 2
1 Merge sort – Ví dụ
Trang 9212 1 6 2
1 Merge sort – Ví dụ
Trang 935 8 12 1 4 6 15 2
1 Merge sort – Ví dụ
k = 4; Phân phối đều luân phiên
Trang 945 8 12 2
1 Merge sort – Ví dụ
Trang 955 4
8 6
12 15 2
1 Merge sort – Ví dụ
Trang 962 4 5 6 8 12 15 1
Trang 972 4 5 6 8 12 15 1
1 Merge sort – Ví dụ
Trang 98Merge Sort – Cài đặt
• Dữ liệu hỗ trợ: 2 mảng b, c:
int b[MAX], c[MAX], nb, nc;
• Các hàm cần cài đặt:
– MergeSort : Sắp xếp mảng (a, N) tăng dần
void MergeSort (int a[], int N);
– Distribute: Phân phối đều luân phiên các dãy con độ dài k từ mảng a vào hai mảng b và c
void Distribute (int a[], int N,
int &nb, int &nc, int k);
– Merge : Trộn mảng b và mảng c vào mảng a
void Merge (int a[], int nb, int nc, int k);
Trang 99Merge sort – Cài đặt
//khai báo 2 mảng phụ
int b[MAX], c[MAX], nb, nc;
void MergeSort(int a[], int N)
Trang 100Merge sort – Cài đặt
void Distribute (int a[], int N,
int &nb, int &nc, int k) {
Trang 101Merge sort – Cài đặt
Trang 102Merge sort – Cài đặt
int &pa, int &pb, int &pc, int k) {
Trang 103– Ch n 1 trong các gi i thu t s p x p trên m ng ọ ả ậ ắ ế ả 1 chi u đ ề ể
s p ắ x p ế các ph n ầ t trong danh ử sách theo m t ộ ho c nhi u ặ ề tiêu chí (đi u ề ki n) ệ
• Sắp xếp danh sách sinh viên theo họ tên
• Sắpxếp danh sách sinh viên giảm dần theo điểm tốt
nghiệp
• Sắp xếp danh sách sinh viên theo họ tên, điểm thi tốt
Trang 1052 Danh sách liên kết
Trang 1062 Danh sách liên kết
Trang 1072 Danh sách liên kết
Trang 1082.1 Danh sách liên kết đơn
Mô tả:
Danh sách liên kết đơn là danh sách gồm nhiều nút mỗi nút
có thông tin cần thiết (thành phần dữ liệu) và một liên kết
(thành phần liên kết) đến nút khác .
Danh sách liên kết đơn cần có 1 pHead trỏ vào nút đầu tiên
và con trỏ pTail trỏ vào nút cuối cùng.
Trang 1092.1 Danh sách liên kết đơn
• Tạo danh sách
– Khai báo danh sách liên kết – Khởi tạo danh sách liên kết – Tạo mới một phần tử để thêm vào danh sách liên kết – Thêm vào đầu danh sách
– Thêm vào cuối danh sách – Xuất dữ liệu của toàn bộ danh sách liên kết – Thêm vào sau một phần tử cho trước
Trang 1102.1 Danh sách liên kết đơn
struct NODE
{
Trang 1112.1 Danh sách liên kết đơn
void KhoiTao(LIST &l)
{
l.pHead =NULL;
l.pTail =NULL;
}
Việc khởi tạo danh sách liên kết nhằm xác định
danh sách ban đầu mới tạo ra là rỗng
Trang 1122.1 Danh sách liên kết đơn
Trang 1132.1 Danh sách liên kết đơn
1 Danh sách rỗng
2 Danh sách đã có phần tử
Trang 114Thêm 1 phần tử vào đầu danh sách
A
L.pHead
L.pTail
Trang 1152.1 Danh sách liên kết đơn
void AddHead(LIST &l, NODE* add)
{
if(IsEmpty(l)) //DS r ng ỗ {
l.pHead=l.pTail=add;
} else {
add->next=l.pHead;
l.pHead=add;
} }
Trang 1162.1 Danh sách liên kết đơn
1 Danh sách rỗng
2 Danh sách đã có phần tử
Trang 1172.1 Danh sách liên kết đơn
void AddTail(LIST &l, NODE* add)
{
if(IsEmpty(l)) //DS r ng ỗ {
l.pHead=l.pTail=add;
} else {
Trang 1182.1 Danh sách liên kết đơn
Trang 1192.1 Danh sách liên kết đơn
Sử dụng 1 con trỏ phụ p để duyệt tất cả các phần tử trong danh sách liên kết
L.pHead
L.pTail
P
Trang 1202.1 Danh sách liên kết đơn
NODE* Search(LIST l, int x)