5.2. Các thuật toán tìm kiếm 5.1. THUẬT TOÁN SẮP XẾP Sắp xếp chọn Sắp xếp nổi bọt Sắp xếp chèn Sắp xếp nhanh Giả sử sắp xếp mảng A gồm n phần tử theo thứ tự tang dần 5.1. THUẬT TOÁN SẮP XẾP 1) Sắp xếp chọn (Selection Sort) Để sắp xếp mảng A gồm n phần tử theo một thứ tự nhất định (tăng dần/giảm dần) lần lượt định vị trí đúng cho n-1 phần tử đầu bằng cách duyệt qua tất cả các phần tử sau nó và kiểm tra nếu sai vị trí so với nó thì đổi giá trị cho nhau. 5.1. THUẬT TOÁN SẮP XẾP void SelectionSort(int A[ ], int n) { int i, j, temp;
for (i=0; i<n-1; i++)
for (j=i+1; j<n; j++) if (A[j]<A[i]) Swap(A[i], A[j]); } 5.1. THUẬT TOÁN SẮP XẾP Thuật toán được cải tiến như sau: void SelectionSort(int A[ ], int n) { int i, j, im, temp;
for (i=0; i<n-1; i++){
im=i; for (j=i+1; j<n; j++) if (A[j]<A[im]) im=j; Swap(A[i], A[im]); } } 5.1. THUẬT TOÁN SẮP XẾP 2) Sắp xếp nổi bọt (Bubble Sort) Lần lượt định vị trí đúng cho n-1 phần tử đầu, khi định vị trí đúng cho phần tử thứ i thì duyệt từ cuối mảng đến phần tử kề nó để hoán đổi hai phần tử kề nhau nếu cần. Tương tự bọt nước trong ống nghiệm. 5.1. THUẬT TOÁN SẮP XẾP void BubbleSort(int A[ ], int n) { int i, j;
for (i=0; i<n-1; i++)
for (j=n-1; j>i; j--) if (A[j]<A[j-1]) Swap(A[j], A[j-1]); } 5.1. THUẬT TOÁN SẮP XẾP 3) Sắp xếp chèn (Insertion Sort) 5.1. THUẬT TOÁN SẮP XẾP Lần lượt duyệt từ phần tử thứ hai cho đến cuối để đưa về đúng vị trí trong phần đã sắp xếp phía trước nó. Khi phần tử đang xét là phần tử thứ i thì lấy phần tử này ra (x=A[i]) và dịch chuyển các phần tử trước nó và lớn hơn nó qua 1 vị trí để có lổ hổng và đưa x vào. 5.1. THUẬT TOÁN SẮP XẾP void InsertionSort(int A[ ], int n) { int i, j, x;
for (i=1; i<n; i++){
x=A[i]; j=i-1; while (j>=0 && A[j]>x){ A[j+1]=A[j]; j--;} A[j+1]=x; } } 5.1. THUẬT TOÁN SẮP XẾP 4) Sắp xếp nhanh (Quick Sort) Thuật toán đệ quy được C.A.R. Hoare đưa ra năm 1960. Thuật toán được cài đặt Qsort(A, left, right) để sắp xếp một phần của mảng A từ left đến right. Giả sử mảng A[0..n-1], chương trình chính gọi Qsort(A, 0, n-1). 5.1. THUẬT TOÁN SẮP XẾP Với Qsort(A, left, right) cần chọn một phần tử x làm phần tử trục (pivot), có thể là phần tử bất kỳ thường là phần tử ở giữa, A[(left+right)/2]. Bước phân hoạch đưa tất cả các phần tử nhỏ hơn x về trước x và lớn hơn x về sau x. 5.1. THUẬT TOÁN SẮP XẾP 1. Quét. Di chuyển i sang phải qua mọi phần tử nhỏ hơn phần tử trục. Di chuyển j sang trái qua mọi phần tử lớn hơn hoặc bằng phần tử trục 2. Kiểm tra. Nếu i>j thì A[left], …, A[right] đã sắp xếp xong. 3. Đổi. Nếu ij thì hoán đổi A[i] và A[j] 4. Gọi đệ quy Qsort(left,j) nếu left<j 5. Gọi đệ quy Qsort(i, right) nếu i<right 5.1. THUẬT TOÁN SẮP XẾP void QuickSort(int A[ ], int left, int right) { int i, j, x; i=left; j=right; x = A[(left+right)/2]; do{ while (A[i]<x) i++; while (A[j]>x) j--; if (i<=j){ Swap(A[i], A[j]); i++; j--; } } while (i<=j); if (j>left) QuickSort(left, j); if (i<right) QuickSort(i, right); } 5.1. THUẬT TOÁN TÌM KIẾM Tìm kiếm tuần tự Tìm kiếm nhị phân 5.2. THUẬT TOÁN TÌM KIẾM 1) Tìm kiếm tuần tự Tìm phần tử x có trong mảng A hay không. Nếu có trả về vị trí xuất hiện đầu tiên i trong A; ngược lại, trả về -1. 5.2. THUẬT TOÁN TÌM KIẾM int Search(int x, int A[ ], int n) { int i;
i=0; while (i<n && A[i]!=x) i++;
if (i>=n) i= -1; return i; } 5.2. THUẬT TOÁN TÌM KIẾM 2) Tìm kiếm nhị phân Chỉ áp dụng cho mảng đã được sắp xếp. • Nếu x bằng phần tử giữa thì kết thúc. • Nếu x nhỏ hơn phần tử giữa thì tìm x ở nửa mảng bên trái. • Nếu x lớn hơn phần tử giữa thì tìm x ở nửa mảng bên phải. 5.2. THUẬT TOÁN TÌM KIẾM int BSearch(int x, int A[ ], int n) { int m, i, j; i=0; j=n-1; while (i<=j){ m = (i+j)/2; if (x == A[m]) return m; if (x < A[m]) j=m-1; else i=m+1; } return -1; } 5.2 THUẬT TOÁN TÌM KIẾM Phiên bản đệ quy int BSearch(int x, int A[ ], int left, int right) { int m; if (left > right) return -1; m = (left + right)/2; if (x == A[m]) return m; if (x < A[m]) return BSearch(x, A, left, m-1); else return BSearch(x, A, m+1, right); } }