xếp luôn là việc so sánh giá trị của 2 phần tử thì Radix Sort lại dựa trên nguyên tắc phân loại thư của bưu điện. Vì lý do đó Radix Sort còn có tên là Postman’s Sort[r]
(1)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
1
TÌM KIẾM VÀ SẮP XẾP NỘI
(2)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
2
Nội Dung
Các giải thuật tìm kiếm nội
1 Tìm kiếm tuyến tính Tìm kiếm nhị phân
Các giải thuật xếp nội
Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
(3)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
3
Nội Dung (tt)
4 Chèn trực tiếp – Insertion Sort
5 Chèn nhị phân – Binary Insertion Sort Shaker Sort
(4)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
4
Bài Tốn Tìm Kiếm
Cho danh sách có n phần tử a0, a1, a2…, an-1
Để đơn giản việc trình bày giải thuật ta dùng mảng
chiều a để lưu danh sách phần tử nói nhớ
Tìm phần tử có khố X mảng
Giải thuật tìm kiếm tuyến tính (tìm tuần tự) Giải thuật tìm kiếm nhị phân
Lưu ý: Trong trình trình bày thuật giải ta dùng ngôn ngữ
(5)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
5
Tìm Kiếm Tuyến Tính
Ý tưởng : So sánh X với phần tử thứ 1,
thứ 2,…của mảng a gặp khóa cần tìm, tìm hết mảng mà khơng thấy
Các bước tiến hành
• Bước 1: Khởi gán i=0;
• Bước 2: So sánh a[i] với giá trị x cần tìm, có khả + a[i] == x tìm thấy x Dừng;
+ a[i] != x sang bước 3;
• Bước 3: i=i+1 // Xét tiếp phần tử mảng Nếu i==N: Hết mảng Dừng;
(6)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
6
Thuật Tốn Tìm Kiếm Tuyến Tính
Hàm trả tìm thấy, ngược lại trả 0:
int LinearSearch(int a[],int n, int x) {
int i=0;
while((i<n)&&(a[i]!=x)) i++;
if(i==n)
return 0; //Tìm khơng thấy x
else
(7)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
7
Minh Họa Thuật Tốn Tìm Kiếm Tuyến Tính
1 2 3 4 5 6
0
2 8 5 1 6 4 6
X=6 i
6
(8)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
8
Minh Họa Thuật Tốn Tìm Kiếm Tuyến Tính (tt)
1 2 3 4 5 6
0
2 8 5 1 6 4 6
X=10 i
(9)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
9
Ðánh Giá Thuật Tốn Tìm Tuyến Tính
Trường hợp Css
Xấu Trung bình
N
(N+1) /
Độ phức tạp O(N)
(10)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
10
Cải Tiến Thuật Tốn Tìm Tuyến Tính
Nhận xét: Số phép so sánh thuật toán trường
hợp xấu 2*n
Để giảm thiểu số phép so sánh vòng lặp cho thuật
tốn, ta thêm phần tử “lính canh” vào cuối dãy
int LinearSearch(int a[],int n, int x)
{ int i=0; a[n]=x; // a[n] phần tử “lính canh”
while(a[i]!=x) i++; if(i==n)
return 0; // Tìm không thấy x
else
(11)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
11
Thuật Tốn Tìm Kiếm Nhị Phân
Được áp dụng mảng có thứ tự.
Ý tưởng:
Giả xử ta xét mảng có thứ tự tăng, ta có
ai-1<ai<ai+1
Nếu X>ai X xuất đoạn [ai+1, a
n-1]
Nếu X<ai X xuất đoạn [a0, a
i-1]
Ý tưởng giải thuật bước ta so sánh X
(12)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
12
Các Bước Thuật Tốn Tìm Kiếm Nhị Phân
Giả sử dãy tìm kiếm hành bao gồm phần tử nằm aleft, aright, bước giải thuật sau:
Bước 1: left=0; right=N-1; Bước 2:
mid=(left+right)/2; //chỉ số phần tử dãy hành So sánh a[mid] với x Có khả năng
• a[mid]= x: tìm thấy Dừng • a[mid]>x : Right= mid-1; • a[mid]<x : Left= mid+1;
Bước 3: Nếu Left <=Right ; // phần tử dãy
hành
(13)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
13
Cài Đặt Thuật Tốn Tìm Nhị Phân
Hàm trả giá trị tìm thấy, ngược lại hàm
trả giá trị
int BinarySearch(int a[],int n,int x)
{ int left, right, mid; left=0; right=n-1;
do{
mid=(left+right)/2;
if(a[mid]==x) return 1;
else if(a[mid]<x) left=mid+1;
else right=mid-1; }while(left<=right);
(14)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
14
Ðánh Giá Thuật Tốn Tìm Tuyến Tính
Trường hợp Css
Xấu Trung bình
log2N log2N /
Độ phức tạp O(logN)
(15)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
15
Minh Họa Thuật Toán Tìm Nhị Phân
1 2 4 6 9 10
X=2 L
2
Tìm thấy vị trí 1
7
1 2 3 4 5 6
0
(16)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
16
1 2 4 6 9 10
X=-1 L
L=0
R=-1 => khơng tìm thấy X=-1
7
1 2 3 4 5 6
0
R M
(17)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
17
Bài Toán Sắp Xếp
Cho danh sách có n phần tử a0, a1, a2…, an-1
Sắp xếp trình xử lý phần tử danh
sách để đặt chúng theo thứ tự thỏa mãn số tiêu chuẩn dựa thơng tin lưu phần tử, như:
Sắp xếp danh sách lớp học tăng theo điểm trung
bình
Sắp xếp danh sách sinh viên tăng theo tên.
…
Để đơn giản việc trình bày giải thuật ta dùng
(18)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
18
Bài Toán Sắp Xếp (tt)
a: dãy phần tử liệu
Để xếp dãy a theo thứ tự (giả sử theo thứ tự tăng),
ta tiến hành triệt tiêu tất nghịch a
Nghịch thế:
• Cho dãy có n phần tử a0, a1,…,an-1
• Nếu i<j >aj
Đánh giá độ phức tạp giải thuật, ta tính
Css: Số lượng phép so sánh cần thực
CHV: Số lượng phép hoán vị cần thực
a[0], a[1] cặp nghịch
(19)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
19
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
(20)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
20
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort
2 Chọn trực tiếp – Selection Sort Nổi bọt – Bubble Sort
4 Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
(21)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
21
Đổi Chỗ Trực Tiếp – Interchange Sort
Ý tưởng: Xuất phát từ đầu dãy, tìm tất
các nghịch chứa phần tử này, triệt tiêu
(22)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
22
Các Bước Tiến Hành
Bước 1: i = 0; // đầu dãy
Bước 2: j = i+1; //tìm nghịch với a[i] Bước 3:
Trong j < N thực
Nếu a[j]<a[i] //xét cặp a[i], a[j] Swap(a[i],a[j]);
j = j+1;
Bước 4: i = i+1;
(23)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
23
Đổi Chỗ Trực Tiếp – Interchange Sort
Cho dãy số a:
12 15
j=1 i=0
(24)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
24
Đổi Chỗ Trực Tiếp – Interchange Sort
i=1 j=2
i=1 j=3
(25)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
25
Đổi Chỗ Trực Tiếp – Interchange Sort
i=2 j=6
i=2 j=4
(26)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
26
Đổi Chỗ Trực Tiếp – Interchange Sort
i=3 j=4
i=3 j=5
(27)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
27
Đổi Chỗ Trực Tiếp – Interchange Sort
i=5 j=6
i=4 j=6
(28)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
28
Đổi Chỗ Trực Tiếp – Interchange Sort
(29)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
29
Cài Đặt Đổi Chỗ Trực Tiếp
void InterchangeSort(int a[], int N ) {
int i, j;
for (i = ; i<N-1 ; i++)
for (j =i+1; j < N ; j++)
if(a[j ]< a[i]) // Thỏa cặp nghịch thế
(30)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
30
Minh Họa Thuật Toán
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
0 1
i
(31)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
31
Minh Họa Thuật Toán
12 8 5 2 6 4 15
1
1 2 3 4 5 6 7
0
2
0 i
(32)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
32
Minh Họa Thuật Toán
2 12 8 5 6 4 15
1
1 2 3 4 5 6 7
0
4
0
i
(33)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
33
Minh Họa Thuật Toán
2 4 12 8 6 5 15
1
1 2 3 4 5 6 7
0
5
0
i
(34)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
34
Minh Họa Thuật Toán
2 4 5 6 8 12 15
1
2 3 4 5 6 7 8
(35)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
35
(36)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
36
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort
2 Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
(37)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
37
Chọn Trực Tiếp – Selection Sort
Ý tưởng:
Chọn phần tử nhỏ N phần tử
dãy hành ban đầu
Đưa phần tử vị trí đầu dãy hành Xem dãy hành N-1 phần tử
dãy hành ban đầu
Bắt đầu từ vị trí thứ 2;
Lặp lại trình cho dãy hành
(38)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
38
Các Bước Của Thuật Toán Chọn Trực Tiếp
Bước 1: i = 0;
Bước 2: Tìm phần tử a[min] nhỏ
dãy hành từ a[i] đến a[N]
Bước : Đổi chỗ a[min] a[i] Bước : Nếu i < N-1
(39)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
39
Chọn Trực Tiếp – Selection Sort
Cho dãy số a:
(40)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
40
Chọn Trực Tiếp – Selection Sort
i=0
(41)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
41
Chọn Trực Tiếp – Selection Sort
i=2
i=3
(42)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
42
Chọn Trực Tiếp – Selection Sort
(43)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
43
Cài Đặt Thuật Toán Chọn Trực Tiếp
void SelectionSort(int a[],int n ) {
int min,i,j; // chỉ số phần tử nhỏ dãy hành
for (i=0; i<n-1 ; i++) //chỉ số dãy hiện hành {
min = i;
for(j = i+1; j <N ; j++)
if (a[j ] < a[min])
min = j; // lưu vtrí phần tử nhỏ
nhất
Swap(a[min],a[i]); }
(44)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
44
Minh Họa Thuật Toán Chọn Trực Tiếp
2 8 5 1 6 4 15
12
i
min
1 2 3 4 5 6 7
0
(45)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
45
Minh Họa Thuật Toán Chọn Trực Tiếp
2 8 5 12 6 4 15
1
i
min
1 2 3 4 5 6 7
0
(46)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
46
Minh Họa Thuật Toán Chọn Trực Tiếp
2 8 5 12 6 4 15
1
i
min
1 2 3 4 5 6 7
0
(47)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
47
Minh Họa Thuật Toán Chọn Trực Tiếp
2 4 5 12 6 8 15
1
i
min
1 2 3 4 5 6 7
0
(48)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
48
Minh Họa Thuật Toán Chọn Trực Tiếp
2 4 5 12 6 8 15
1
i
min
1 2 3 4 5 6 7
0
(49)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
49
Minh Họa Thuật Toán Chọn Trực Tiếp
2 4 5 6 12 8 15
1
i
min
1 2 3 4 5 6 7
0
(50)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
50
Minh Họa Thuật Toán Chọn Trực Tiếp
2 4 5 6 8 12 15
1
i
min
1 2 3 4 5 6 7
0
V trí nh nh t(6, 7)ị ỏ ấ
(51)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
51
Độ Phức Tạo Của Thuật Toán
Ðánh giá giải thuật
1
( 1)
số lần so sánh ( )
2 n
i
n n n i
(52)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
52
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort
4 Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
(53)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
53
Nổi Bọt – Bubble Sort
Ý tưởng:
Xuất phát từ cuối dãy, đổi chỗ cặp phần tử
kế cận để đưa phần tử nhỏ cặp phần tử vị trí đầu dãy hành, sau khơng xét đến bước tiếp theo, lần xử lý thứ i có vị trí đầu dãy i
Lặp lại xử lý khơng cịn cặp
(54)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
54
Nổi Bọt – Bubble Sort
Bước : i = 0; // lần xử lý
Bước : j = N-1;//Duyệt từ cuối dãy ngược vị trí i
Trong (j > i) thực hiện: Nếu a[j]<a[j-1]
Doicho(a[j],a[j-1]);
j = j-1;
Bước : i = i+1; // lần xử lý kế tiếp
Nếu i =N: Hết dãy Dừng
(55)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
55
Nổi Bọt – Bubble Sort
Cho dãy số a:
2 12 15
i=0 j=6
(56)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
56
Nổi Bọt – Bubble Sort
i=0 j=1
i=0 j=2
(57)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
57
Nổi Bọt – Bubble Sort
i=1 j=3
i=1 j=4
(58)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
58
Nổi Bọt – Bubble Sort
i=2 j=5
i=2 j=4
(59)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
59
Nổi Bọt – Bubble Sort
i=5
i=4 j=6
(60)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
60
Cài Đặt Thuật Toán Nổi Bọt void BubbleSort(int a[],int n) {
int i, j;
for (i = ; i<n-1 ; i++)
for (j =n-1; j >i ; j )
if(a[j]< a[j-1])// sai vị trí đổi chỗ Swap(a[j], a[j-1]);
(61)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
61
Minh Họa Thuật Toán
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
0
i
j
(62)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
62
Minh Họa Thuật Toán
12 2 8 5 4 6 15
1
1 2 3 4 5 6 7
0
i
j
(63)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
63
Minh Họa Thuật Toán
2 12 4 8 5 6 15
1
1 2 3 4 5 6 7
0
i
j
(64)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
64
Minh Họa Thuật Toán
2 4 12 8 5 6 15
1
1 2 3 4 5 6 7
0
i
j
(65)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
65
Minh Họa Thuật Toán
2 4 5 12 8 6 15
1
1 2 3 4 5 6 7
0
i
j
(66)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
66
Minh Họa Thuật Toán
2 4 5 6 12 8 15
1
1 2 3 4 5 6 7
0
i
j
(67)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
67
Minh Họa Thuật Toán
2 4 5 6 8 12 15
1
2 3 4 5 6 7 8
1
i
j
(68)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
68
(69)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
69
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort
4 Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
(70)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
70
Shaker Sort
Trong lần xếp, duyệt mảng theo lượt từ
2 phía khác nhau:
Lượt đi: đẩy phần tử nhỏ đầu mảng. Lượt về: đẩy phần tử lớn cuối mảng Ghi nhận lại đoạn xếp nhằm tiết
(71)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
71
Các Bước Của Thuật Toán
Bước 1: l=0; r=n-1; //Đoạn l->r đoạn cần xếp
k=n; //ghi nhận vị trí k xảy hoán vị sau // để làm sơ thu hẹp đoạn l->r
Bước 2:
Bước 2a:
j=r; //đẩy phần tử nhỏ đầu mảng Trong j>l
nếu a[j]<a[j-1] {Doicho(a[j],a[j-1]): k=j;}
j ;
l=k; //loại phần tử có thứ tự đầu dãy Bước 2b: j=l
Trong j<r
nếu a[j]>a[j+1] {Doicho(a[j],a[j+1]); k=j;}
j++;
r=k; //loại phần tử có thứ tự cuối dãy
Bước 3: Nếu l<r lặp lại bước 2
(72)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
72
Cài Đặt Thuật Toán Shaker Sort
void ShakeSort(int a[],int n) {
int i, j;
int left, right, k;
left = 0; right = n-1; k = n-1;
while (left < right) {
for (j = right; j > left; j ) if (a[j]< a[j-1])
{Swap(a[j], a[j-1]);k =j;} left = k;
for (j = left; j < right; j ++) if (a[j]> a[j+1])
{Swap(a[j], a[j-1]);k = j; } right = k;
(73)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
73
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
(74)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
74
Chèn Trực Tiếp – Insertion Sort
Giả sử có dãy a0 , a1 , ,an-1 i phần
tử a0 , a1 , ,ai-1 có thứ tự
Tìm cách chèn phần tử ai vào vị trí thích hợp
đoạn để có dãy a0 , a1, ,ai trở
(75)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
75
Chèn Trực Tiếp – Insertion Sort
Bước 1: i = 1;//giả sử có đoạn a[1] sắp
Bước 2: x = a[i]; Tìm vị trí pos thích hợp
đoạn a[1] đến a[i-1] để chèn a[i] vào
Bước 3: Dời chỗ phần tử từ a[pos] đến a[i-1]
sang phải vị trí để dành chổ cho a[i]
Bước 4: a[pos] = x; //có đoạn a[1] a[i] Bước 5: i = i+1;
(76)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
76
Chèn Trực Tiếp – Insertion Sort
Cho dãy số :
12 15
i=1
(77)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
77
Chèn Trực Tiếp – Insertion Sort
i=3
i=4
(78)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
78
Chèn Trực Tiếp – Insertion Sort
i=6
(79)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
79
Cài Đặt Thuật Toán Chèn Trực Tiếp
void InsertionSort(int d, int n ) { int pos, i;
int x;//lưu giá trị a[i] tránh bị ghi đè dời chỗ phần tử
for(i=1 ; i<n ; i++) //đoạn a[0]
{
x = a[i]; pos = i-1;
// tìm vị trí chèn x
while((pos >= 0)&&(a[pos] > x))
{//kết hợp dời chỗ phần tử đứng sau x dãy
a[pos+1] = a[pos]; pos ;
}
a[pos+1] = x; // chèn x vào dãy
(80)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
80
Minh Họa Thuật Toán Insertion Sort
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
(81)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
81
2 8 5 1 6 4 15
12
i
x
1 2 3 4 5 6 7
0
pos
2
Minh Họa Thuật Toán Insertion Sort
(82)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
82
12 8 5 1 6 4 15
2
i
x
1 2 3 4 5 6 7
0
pos
Minh Họa Thuật Toán Insertion Sort
Insert a[2] into (0, 1)
(83)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
83
8 12 5 1 6 4 15
2
i
x
1 2 3 4 5 6 7
0
pos
Minh Họa Thuật Toán Insertion Sort
Insert a[3] into (0, 2)
(84)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
84
5 8 12 1 6 4 15
2
i
x
1 2 3 4 5 6 7
0
pos
Minh Họa Thuật Toán Insertion Sort
Insert a[4] into (0, 3)
(85)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
85
2 5 8 12 6 4 15
1
i
x
1 2 3 4 5 6 7
0
pos
Minh Họa Thuật Toán Insertion Sort
Insert a[5] into (0, 4)
(86)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
86
2 5 6 8 12 4 15
1
i
x
1 2 3 4 5 6 7
0
pos
Minh Họa Thuật Toán Insertion Sort
Insert a[6] into (0, 5)
(87)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
87
2 4 5 6 8 12 15
1
i
x
1 2 3 4 5 6 7
0
pos
Minh Họa Thuật Toán Insertion Sort
Insert a[8] into (0, 6)
(88)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
88
2 4 5 6 8 12 15
1
pos
1 2 3 4 5 6 7
0
(89)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
89
(90)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
90
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort
(91)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
91
Chèn Nhị Phân – Binary Insertion Sort
Thuật toán xếp chèn trình bày phần
trước thực phép tìm kiếm tuyến tính để tìm vị trí cần chèn Tuy nhiên, chèn phần tử vào dãy xếp, sử
dụng tìm kiếm nhị phân thay tìm kiếm tuyến tính Trong tìm kiếm tuyến tính đòi hỏi
O(n) phép so sánh trường hợp xấu nhất, tìm kiếm nhị phân yêu cầu O(nlogn)
phép so sánh Vì vậy, chi phí việc so
(92)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
92
Chèn Nhị Phân – Binary Insertion Sort
void BInsertionSort(int a[],int n ) {
int l,r,m,i;
int x;//lưu giá trị a[i] tránh bị ghi đè dời chỗ phần tử
for(int i=1 ; i<n ; i++) {
x = a[i]; l = 0; r = i-1;
while(l<=r)// tìm vị trí chèn x tìm kiếm nhị phân
{
m = (l+r)/2; if (x < a[m]) r = m-1; else
l = m+1; }
//Vị trí chèn L
for (int j = i-1 ; j >=l ; j )
a[j+1] = a[j];// dời phần tử đứng sau x
a[l] = x;// chèn x vào dãy
(93)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
93
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort
7 Shell Sort
(94)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
94
Shell Sort
Cải tiến phương pháp chèn trực tiếp Ý tưởng:
Phân hoạch dãy thành dãy con
Sắp xếp dãy theo phương pháp chèn
trực tiếp
Dùng phương pháp chèn trực tiếp xếp lại
(95)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
95
Shell Sort
Phân chia dãy ban đầu thành dãy gồm
phần tử cách h vị trí
Dãy ban đầu : a1, a2, , an xem xen kẽ
các dãy sau :
Dãy thứ : a1 ah+1 a2h+1 Dãy thứ hai : a2 ah+2 a2h+2
(96)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
96
Shell Sort
Tiến hành xếp phần tử dãy làm
cho phần tử đưa vị trí tương đối
Giảm khoảng cách h để tạo thành dãy
(97)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
97
Shell Sort
Giả sử định xếp k bước, khoảng cách
chọn phải thỏa điều kiện :
hi > hi+1 hk =
hi = (hi-1 - 1)/3 hk = 1, k = log3n-1
Ví dụ :127, 40, 13, 4,
hi = (hi-1 - 1)/2 hk = 1, k = log2n-1
(98)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
98
Shell Sort
h có dạng 3i+1: 364, 121, 40, 13, 4, 1
Dãy fibonaci: 34, 21, 13, 8, 5, 3, 2, 1
h dãy số nguyên tố giảm dần đến 1: 13, 11, 7, 5, 3,
(99)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
99
Shell Sort
Bước 1: Chọn k khoảng cách h[1], h[2], , h[k];
i = 1;
Bước 2: Phân chia dãy ban đầu thành dãy
cách h[i] khoảng cách
Sắp xếp dãy phương pháp chèn trực tiếp;
Bước 3 : i = i+1;
Nếu i > k : Dừng
(100)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
100
Shell Sort
Cho dãy số a:
12 15
(101)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
101
Shell Sort
(102)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
102
Shell Sort
(103)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
103
Shell Sort
(104)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
104
(105)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
105
Shell Sort
void ShellSort(int a[],int n, int h[], int k) { int step,i,j, x,len;
for (step = ; step <k; step++) { len = h[step];
for (i = len; i<n; i++) {
x = a[i];
j = i-len; // a[j] đứng kề trước a[i] dãy
while ((x<a[j])&&(j>=0)// xếp dãy chứa x
{ // phương pháp chèn trực tiếp
a[j+len] = a[j]; j = j - len;
}
a[j+len] = x; }
(106)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
106
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
0
Shell Sort – Ví Dụ
h = (5, 3, 1); k = 3 len = 5
curr
(107)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
107
2 8 5 1 12 4 15
6
1 2 3 4 5 6 7
0
Shell Sort – Ví Dụ
(108)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
108
2 15 5 1 12 4 8
6
1 2 3 4 5 6 7
0
Shell Sort – Ví Dụ
h = (5, 3, 1); k = 3 len = 3
curr
(109)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
109
1 12 6 2 15 4 8
5
1 2 3 4 5 6 7
0
Shell Sort – Ví Dụ
h = (5, 3, 1); k = 3 len = 3
curr
(110)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
110
1 12 5 2 15 6 8
4
Shell Sort – Ví Dụ
h = (5, 3, 1); k = 3 len = 3
1 2 3 4 5 6 7
(111)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
111 jointcurr
1 12 5 2 15 6 8
4
1 2 3 4 5 6 7
0
Shell Sort – Ví Dụ
h = (5, 3, 1); k = 3 len = 1
(112)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
112
jointcurr
joint
4 5 12 2 15 6 8
1
1 2 3 4 5 6 7
0
Shell Sort – Ví Dụ
h = (5, 3, 1); k = 3 len = 1
(113)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
113
2 4 5 6 8 12 15
1
Shell Sort – Ví Dụ
1 2 3 4 5 6 7
(114)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
114
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
8 Heap Sort
(115)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
115
Thuật Toán Sắp Xếp Heap Sort
Heap Sort tận dụng phép so sánh
bước i-1 mà thuật toán xếp chọn trực tiếp không tận dụng
Để làm điều Heap sort thao tác dựa
(116)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
116
Thuật Toán Sắp Xếp Heap Sort
Cho dãy số : 12 15
0
a[6]
12
2 8
5 1 6 4
15
a[0]
a[1] a[2]
a[3] a[4] a[5]
(117)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
117
Thuật toán xếp Heap Sort
Ở trên, phần tử mức i phần tử lớn
trong cặp phần tử mức i +1, phần tử nút gốc phần tử lớn
Nếu loại bỏ gốc khỏi cây, việc cập nhật
chỉ xảy nhánh liên quan đến phần tử loại bỏ, nhánh khác bảo tồn
Bước sử dụng lại kết so sánh
của bước
(118)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
118
Các Bước Thuật Toán
Giai đoạn : Hiệu chỉnh dãy số ban đầu thành
heap
Giai đoạn 2: Sắp xếp dãy số dựa heap:
Bước 1:Đưa phần tử lớn vị trí
cuối dãy:
r = n-1; Swap (a1 , ar );
Bước 2: Loại bỏ phần tử lớn khỏi heap:
r = r-1;
Hiệu chỉnh phần lại dãy từ a1 , a2 ar thành heap
Bước 3:
(119)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
119
Minh Họa Thuật Toán
Heap: Là dãy phần tử al, al+1 , , ar thoả quan hệ với i [l, r]:
ai a2i+1
ai a2i+2 // (ai , a2i+1), (ai , a2i+2 ) cặp phần tử liên đới
Cho dãy số : 12 15
Giai đoạn 1: Hiệu chỉnh dãy ban đầu thành Heap
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
0
l=3
(120)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
120
Minh Họa Thuật Toán
2 8 15 1 6 4 5
12
1 2 3 4 5 6 7
0
l=2 Pt liên
đới
2 8 15 1 6 4 5
12
1 2 3 4 5 6 7
0
l=1 Pt liên
(121)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
121
Minh Họa Thuật Toán
15 8 2 1 6 4 5
12
1 2 3 4 5 6 7
0
l=1 Lan truyền việc điều chỉnh
15 8 5 1 6 4 2
12
1 2 3 4 5 6 7
0
l=0 Pt liên
(122)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
122
Minh Họa Thuật Toán
12 8 5 1 6 4 2
15
Giai đoạn 2: Sắp xếp dãy số dựa Heap
12 8 5 1 6 4 2
15
12 8 5 1 6 4 15
2
1 2 3 4 5 6 7
0
1 2 3 4 5 6 7
0
1 2 3 4 5 6 7
0
(123)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
123
Minh Họa Thuật Toán
Hiệu chỉnh Heap
12 8 5 1 6 4 15
2
1 2 3 4 5 6 7
0
l=2 Pt liên
đới
12 8 5 1 6 4 15
2
1 2 3 4 5 6 7
0
l=2 Pt liên
(124)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
124
Minh Họa Thuật Toán
12 8 5 1 6 4 15
2
1 2 3 4 5 6 7
0
l=0 Pt liên
đới
2 8 5 1 6 4 15
12
l=2
1 2 3 4 5 6 7
(125)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
125
Minh Họa Thuật Toán
2 8 5 1 6 4 15
12
l=2
1 2 3 4 5 6 7
0
Lan truyền việc điều chỉnh
5 8 2 1 6 4 15
12
l=2
1 2 3 4 5 6 7
(126)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
126
Minh Họa Thuật Toán
5 8 2 1 6 4 15
12
1 2 3 4 5 6 7
0
5 8 2 1 6 12 15
4
1 2 3 4 5 6 7
0
Thực với r= 5,4,3,2 ta được
2 4 5 6 8 12 15
1
1 2 3 4 5 6 7
(127)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
127
Cài Đặt Thuật Toán
Hiệu chỉnh al, al+1, ,ar thành Heap
void shift(int a[],int l,int r) {
int x,i,j; i=l;
j=2*i+1; x=a[i];
while(j<=r) { if(j<r)
(128)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
128
Cài Đặt Thuật Toán
j++; //luu chi so cua phan tu nho nhat hai phan tu
if(a[j]<=x) return;
else
{ a[i]=a[j]; a[j]=x;
i=j;
j=2*i+1; x=a[i]; }
}
(129)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
129
Cài Đặt Thuật Toán
Hiệu chỉnh a0, an-1Thành Heap
void CreateHeap(int a[],int n) { int l;
l=n/2-1;
while(l>=0) {
shift(a,l,n-1); l=l-1;
(130)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
130
Cài Đặt Thuật Toán
Hàm HeapSort
void HeapSort(int a[],int n) { int r;
CreateHeap(a,n); r=n-1;
while(r>0) {
Swap(a[0],a[r]);//a[0] la nút gốc
r ;
if(r>0)
shift(a,0,r); }
(131)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
131
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
8 Heap Sort
9 Quick Sort
(132)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
132
Quick Sort
Ý tưởng:
Giải thuật QuickSort xếp dãy a1, a2 , aN dựa
việc phân hoạch dãy ban đầu thành phần :
• Phần 1: Gồm phần tử có giá trị bé
x
• Phần 2: Gồm phần tử có giá trị x
• Phần 3: Gồm phần tử có giá trị lớn
x
(133)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
133
Quick Sort - Ý Tưởng
Sau thực phân hoạch, dãy ban đầu phân thành
đoạn:
• ak ≤ x , với k = j
• ak = x , với k = j+1 i-1
(134)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
134 Đoạn thứ có thứ tự
Nếu đoạn có phần tử : có thứ tự dãy ban đầu
(135)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
135 Đoạn thứ có thứ tự
Nếu đoạn có nhiều phần tử dãy
ban đầu có thứ tự đoạn 1,
Để xếp đoạn 3, ta tiến hành việc
phân hoạch dãy theo phương pháp phân hoạch dãy ban đầu vừa trình bày …
(136)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
136
Giải Thuật Quick Sort
Bước 1: Nếu left ≥ right //dãy có phần tử
Kết thúc; //dãy xếp
Bước 2: Phân hoạch dãy aleft … aright thành đoạn:
aleft aj, aj+1 ai-1, aright
Đoạn x
Đoạn 2: aj+1 ai-1 = x
Đoạn 3: aright x
(137)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
137
Giải Thuật Quick Sort
Bước : Chọn tùy ý phần tử a[k] dãy
giá trị mốc ( l ≤ k ≤ r):
x = a[k]; i = l; j = r;
Bước : Phát hiệu chỉnh cặp phần tử
a[i], a[j] nằm sai chỗ :
Bước 2a : Trong (a[i]<x) i++; Bước 2b : Trong (a[j]>x) j ;
Bước 2c : Nếu i< j Swap(a[i],a[j]);
Bước : Nếu i < j: Lặp lại Bước 2.
(138)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
138
Quick Sort – Ví Dụ
Cho dãy số a:
12 15
Phân hoạch đoạn l =0, r = 7: x = a[3] =
12 2 8 5 1 6 4 15
(139)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
139
Quick Sort – Ví Dụ
4 2 8 5 1 6 12 15
l=0 r=7
4 2 8 5 1 6 12 15
l=0 r=7
j = 6 i = 0
i = 1
j = 5 i = 2
(140)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
140
i = 0 j = 2
Quick Sort – Ví Dụ
4 2 1 5 8 6 12 15
l = r =3
(141)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
141
Quick Sort – Ví Dụ
Phân hoạch đoạn l =4, r = 7:
1 2 4 5 8 6 12
r =7 l =
15
i = 4
1 2 4 5 6 8 12
r =7 l =
(142)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
142
Quick Sort – Ví Dụ
Phân hoạch đoạn l =6, r = 7:
(143)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
143
Quick Sort
void QuickSort(int a[], int left, int right) { int i, j, x;
x = a[(left+right)/2]; i = left; j = right;
{
while(a[i] < x) i++; while(a[j] > x) j ; if(i <= j)
{
Swap(a[i],a[j]); i++ ; j ;
}
} while(i <= j); if(left<j)
QuickSort(a, left, j); if(i<right)
(144)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
144
Quick Sort – Ví Dụ
2 8 1 6 4 15
12
1 2 3 4 5 6 7
0
left right
i j
5
X
5
(145)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
145
Quick Sort – Ví Dụ
2 8 5 1 6 12 15
4
1 2 3 4 5 6 7
0
left right
5
X
i j
(146)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
146
Quick Sort – Ví Dụ
2 1 5 8 6 12 15
4
1 2 3 4 5 6 7
0
left right
i j
(147)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
147
2 1 5 8 6 12 15
4
1 2 3 4 5 6 7
0
left right
i j
X 2
(148)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
148
Quick Sort – Ví Dụ
2 4 5 8 6 12 15
1
1 2 3 4 5 6 7
0
left right
i j
Phân hoạch đọan [4,7]
X
(149)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
149
Quick Sort – Ví Dụ
2 4 5 6 8 12 15
1
1 2 3 4 5 6 7
0
left right
i j
(150)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
150
Quick Sort – Ví Dụ
Phân hoạch đọan [5,7]
2 4 5 6 8 12 15
1
1 2 3 4 5 6 7
0
left right
i j
(151)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
151
Quick Sort – Ví Dụ
2 4 5 6 8 12 15
1
1 2 3 4 5 6 7
(152)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
152
(153)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
153
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort
3 Nổi bọt – Bubble Sort Shaker Sort
5 Chèn trực tiếp – Insertion Sort
6 Chèn nhị phân – Binary Insertion Sort Shell Sort
8 Heap Sort Quick Sort
10 Merge Sort
(154)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
154
Merge Sort – Ý Tưởng
Giải thuật Merge sort xếp dãy a1, a2, , an dựa nhận xét sau:
Mỗi dãy a1, a2, , an tập hợp dãy liên tiếp mà dãy có thứ tự
Ví dụ: dãy 12, 2, 8, 5, 1, 6, 4, 15 coi
gồm dãy không giảm (12); (2, 8); (5); (1, 6); (4, 15)
Dãy có thứ tự coi có dãy con.
Hướng tiếp cận: tìm cách làm giảm số dãy
(155)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
155
Merge Sort – thuật toán
Bước : // Chuẩn bị
k = 1; // k chiều dài dãy bước hành Bước :
Tách dãy a0, a1, , an-1 thành dãy b, c theo nguyên tắc luân
phiên nhóm k phần tử:
b = a0, , ak, a2k, , a3k,
c = ak+1, , a2k+1, a3k+1,
Bước :
Trộn cặp dãy gồm k phần tử dãy b, c vào a Bước :
k = k*2;
(156)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
156
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
Phân phối luân
phiên
(157)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
157
2 8 5 1 6 4 15
12
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k = 1 Phân phối luân
(158)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
158
2
8
5
1
6
4
15
12
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
Trộn cặp đường
(159)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
159
2
8 5
1 6
4 15
12
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
1
Trộn cặp đường
(160)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
160
12 5 8 1 6 4 15
2
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
2
Phân phối luân
(161)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
161
5
12
8
1
4
6
15
2
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
2
Trộn cặp đường
(162)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
162
5
12 8
1 4
6 15
2
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
2
Trộn cặp đường
(163)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
163
5 8 12 1 4 6 15
2
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
4
Phân phối luân
(164)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
164
1
5
4
8
6
12
15
2
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
4
Trộn cặp đường
(165)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
165
1
5 4
8 6
12 15 2
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
4
Trộn cặp đường
(166)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
166
2 4 5 6 8 12 15
1
1 2 3 4 5 6 7
0
Merge Sort – Ví Dụ
k =
(167)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
167
2 4 5 6 8 12 15
1
2 3 4 5 6 7 8
1
(168)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
168
Merge Sort – Cài Đặt
Dữ liệu hỗ trợ: mảng b, c:
int b[MAX], c[MAX], nb, nc;
Các hàm cần cài đặt:
void MergeSort(int a[], int N); : Sắp xếp mảng (a, N)
tăng dần
void Distribute(int a[], int N, int &nb, int &nc, int k);
Phân phối luân phiên dãy độ dài k từ mảng a vào hai mảng b c
void Merge(int a[], int nb, int nc, int k); : Trộn mảng b
và mảng c vào mảng a
void MergeSubarr(int a[], int nb, int nc, int &pa, int
(169)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
169
Merge Sort – Cài Đặt
int b[MAX], c[MAX], nb, nc; void MergeSort(int a[], int N) {
int k;
for (k = 1; k < N; k *= 2) {
Distribute(a, N, nb, nc, k); Merge(a, nb, nc, k);
(170)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
170
Merge Sort – Cài Đặt
void Distribute(int a[], int N, int &nb, int &nc, int k) {
int i, pa, pb, pc; pa = pb = pc = 0;
while (pa < N)
{
for (i=0; (pa<N) && (i<k); i++, pa++, pb++) b[pb] = a[pa];
for (i=0; (pa<N) && (i<k); i++, pa++, pc++) c[pc] = a[pa];
}
(171)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
171
Merge Sort – Cài Đặt
void Merge(int a[],int nb, int nc,int k) { int p, pb, pc, ib, ic, kb, kc;
p=pb=pc=0; ib=ic=0; while((nb>0)&&(nc>0))
{ kb=min(k,nb); kc=min(k,nc); if(b[pb+ib]<=c[pc+ic])
{ a[p++]=b[pb+ib]; ib++; if(ib==kb)
{ for(;ic<kc;ic++ a[p++]=c[pc+ic]; pb+=kb; pc+=kc; ib = ic=0;
nb-=kb; nc-=kc; }
(172)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
172
Merge Sort – Cài Đặt else
{ a[p++]=c[pc+ic]; ic++; if(ic==kc)
{
for(;ib<kb;ib++) a[p++]=b[pb+ib]; pb+=kb; pc+=kc; ib = ic=0;
nb-=kb; nc-=kc; }
(173)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
173
Merge Sort – Cài Đặt
int min(int a,int b) {
(174)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
174
Độ phức tạp Merge Sort
Số lần lặp Bước 2, log2n sau lần
(175)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
175
Các Thuật Toán Sắp Xếp
1 Đổi chỗ trực tiếp – Interchange Sort Nổi bọt – Bubble Sort
3 Shaker Sort
4 Chèn trực tiếp – Insertion Sort
5 Chèn nhị phân – Binary Insertion Sort Shell Sort
7 Chọn trực tiếp – Selection Sort Quick Sort
(176)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
176
Sắp Xếp Theo Phương Pháp Cơ Số Radix Sort
Radix Sort thuật toán tiếp cận theo
hướng hoàn toàn khác
Nếu thuật toán khác, sở để
xếp việc so sánh giá trị phần tử Radix Sort lại dựa nguyên tắc phân loại thư bưu điện Vì lý Radix Sort cịn có tên Postman’s Sort
Radix Sort không quan tâm đến việc so sánh
(177)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
177
Sắp Xếp Theo Phương Pháp Cơ Số Radix Sort
Mô lại qui trình trên, để xếp dãy a1, a2,
, an, giải thuật Radix Sort thực sau: Trước tiên, ta giả sử phần tử ai
trong dãy a1, a2, , an số nguyên có tối đa m chữ số
Ta phân loại phần tử theo
chữ số hàng đơn vị, hàng chục, hàng trăm, … tương tự việc phân loại thư theo tỉnh
(178)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
178
Sắp Xếp Theo Phương Pháp Cơ Số Radix Sort
Bước :// k cho biết chữ số dùng để phân loại
hiện hành
k = 0; // k = 0: hàng đơn vị; k = 1: hàng
chục; …
Bước : //Tạo lô chứa loại phần tử khác
nhau
(179)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
179
Sắp Xếp Theo Phương Pháp Cơ Số Radix Sort
Bước :
For i = n do
Đặt ai vào lô Bt với t: chữ số thứ k ai; Bước :
Nối B0, B1, …, B9 lại (theo trình tự)
thành a
Bước :
k = k+1;Nếu k < m trở lại bước Ngược
(180)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
180
(181)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
181
(182)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
182
(183)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
183
(184)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
184
(185)C
Ấ
U
T
R
Ú
C
D
Ữ
L
IỆ
U
V
À
G
IẢ
I
T
H
U
Ậ
T
1
185
Bài Tập
Nhập dãy số nguyên n phần tử. Sắp xếp lại dãy cho:
số nguyên dương đầu đầu dãy
theo thứ tự giảm
số nguyên âm tăng cuối dãy theo
thứ tự tăng
số giữa.