You are on page 1of 535

TRƯỜNG ĐẠI HỌC NGÂN HÀNG TPHCM

KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 1
Tổng quan
GIẢI THUẬT ỨNG DỤNG
1 TRONG KINH DOANH
Giải thuật ứng dụng trong kinh doanh

Nội dung

Vai trò của tổ chức dữ liệu


Mối quan hệ giữa cấu trúc dữ liệu và giải thuật
Các kiểu dữ liệu cơ bản và điểm yếu
Trừu tượng hóa dữ liệu và cách biểu diễn dữ liệu
trên máy tính
Phân tích và thiết kế giải thuật
Tổng quan về đánh giá độ phức tạp của giải thuật

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Giải thuật ứng dụng trong kinh doanh

Vai trò của tổ chức dữ liệu

Làm thế nào để đưa những công việc ngoài đời


thực vào máy tính để xử lý một cách chính xác và
nhanh chóng nhất có thể?
Những công việc ngoài đời thực gồm những gì?
 Các đối tượng dữ liệu
 Các yêu cầu xử lý trên những đối tượng đó.
 Tổ chức biểu diễn các đối tượng ngoài đời lên máy tính:
Biểu diễn dữ liệu
Xây dựng các thao tác xử lý trên dữ liệu:
Giải thuật

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 3


Giải thuật ứng dụng trong kinh doanh

Vai trò của tổ chức dữ liệu

Ví dụ: Để tính lương cho Công nhân trong công ty


thì có những đối tượng dữ liệu nào tham gia? Yêu
cầu xử lý trên những đối tượng này là gì?

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Giải thuật ứng dụng trong kinh doanh

Vai trò của tổ chức dữ liệu

Dữ liệu
Đối tượng

Bài toán cần


giải quyết

Cách thức
Giải Thuật
giải quyết

Phân tích Lập trình


GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 5
Giải thuật ứng dụng trong kinh doanh

Vai trò của tổ chức dữ liệu

Là những số liệu rời rạc của một sự


vật hiện tượng cần được quản lý.
Ví dụ:
 Nhân viên: Mã, họ tên, địa chỉ, số
điện thoại, lương , hệ số lương…
 Sản Phẩm: Mã, tên sản phẩm, giá,
xuất xứ, ngày sản xuất…

Cần biểu diễn các dữ liệu này vào


máy tính khi xây dựng chương trình.

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Giải thuật ứng dụng trong kinh doanh

Vai trò của tổ chức dữ liệu

 Thực hiện các thao tác trên dữ liệu


đã lưu trữ
 Thao tác : Tìm kiếm, sửa đổi, xóa,
biến đổi dữ liệu, lập báo cáo...
Thao tác  Ví dụ:
trên • Tìm nhân viên có tên:
Dữ Liệu “Nguyễn Thị Phương Thảo”
• Lập danh sách nhân viên có
lương trên 5 triệu theo thứ tự
giảm dần
• Lập danh sách nhân viên có thâm
niên trên 10 năm
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 7
Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật

+ Giải
thuật = Chương
trình

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật


Ví dụ:
Một chương trình quản lý điểm thi của sinh viên cần
lưu trữ các điểm số của 4 sinh viên. Do mỗi sinh viên
có 3 điểm số ứng với 3 môn học khác nhau nên dữ liệu
có dạng bảng như sau:
Sinh viên Điểm 1 Điểm 2 Điểm 3
sv1 3 4 5
sv2 5 9 3
sv3 4 4 6
sv4 4 3 8

Chỉ xét thao tác xử lý là xuất điểm số các môn của


từng sinh viên.
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 9
Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật

Phương án 1 : Sử dụng mảng một chiều: 1D array


3 4 5 5 9 3 4 4 6 4 3 8

Sv1 sv2 sv3 sv4

float diemsv[ ]=new float[12]


Để in điểm thứ i của sv thứ j ta sẽ dùng:
diemsv[(j-1)*3+i-1]

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật

Phương án 2 : Sử dụng mảng hai chiều: matrix


J=0 J=1 J=2

i=0 3 4 5
i=1 5 9 3
i=2 4 4 6
i=3 4 3 8

float [,] diemsv=new float[4,3];


Để in điểm thứ i của sv thứ j ta sẽ dùng:
diemsv[j-1][i-1]

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 11


Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật

Phương án 3 : Sử dụng 3 mảng độc lập


Diem1[4] 3 4 5
Diem2[4]
Diem3[4] 5 9 3

4 4 6
Để in điểm thứ i của sv thứ j ta
sẽ dùng: diemj[i-1]
4 3 8

Điểm 1 Điểm 2 Điểm 3


GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 12
Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật


Phương án 4 : Sử dụng cấu trúc lớp phức hợp
 Màu đỏ: điểm 1
3 4 5
 Màu xanh biển: điểm 2 dSv

 Màu xanh lá: điểm 3


class dSv{
Float Diem1; dSv 5 9 3
Float Diem2;
Float Diem3;
Float dtb;

} dSv 4 4 6
dSv mangdiem[4];
Điểm 1 của sinh viên thứ 3
Mangdiem[2].diem1 4 3 8
dSv

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 13


Giải thuật ứng dụng trong kinh doanh

Mối quan hệ giữa cấu trúc dữ liệu và giải thuật

Mối quan hệ
 Một cấu trúc đã chọn sẽ có những giải thuật
tương ứng
 Khi cấu trúc dữ liệu thay đổi thì giải thuật cũng
thay đổi theo cho phù hợp
 Cấu trúc dữ liệu tốt sẽ giúp giải thuật xử lý phát
huy tốt
Tổ chức cấu trúc dữ liệu trước, sau đó xây dựng
giải thuật xử lý.
Nói cách khác:
Cấu trúc dữ liệu quyết định giải thuật
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 14
Giải thuật ứng dụng trong kinh doanh

Đặc trưng của giải thuật

• Tính xác định


• Tính dừng (hữu hạn)
• Tính đúng đắn
• Tính phổ dụng
• Tính khả thi

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 15


Giải thuật ứng dụng trong kinh doanh

Diễn đạt giải thuật


• Dạng lưu đồ (sơ đồ khối)
• Dạng ngôn ngữ tự nhiên (Ngôn ngữ liệt kê từng bước)
• Ngôn ngữ lập trình
• Dạng mã giả:

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 16


Giải thuật ứng dụng trong kinh doanh

Diễn đạt giải thuật


Các nút biểu diễn giải thuật bằng sơ đồ khối

Nút thao tác:

Nút điều khiển: trong đó ghi điều kiện cần kiểm


tra trong quá trình tính toán.

Nút khởi đầu, kết thúc:

Cung :.

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 17


Giải thuật ứng dụng trong kinh doanh

Diễn đạt giải thuật


Begin Ví dụ : Giải PT: ax2 + bx + c= 0,
giải thuật mô tả bằng sơ đồ khối
Nhập a, b, c

a=0  = b2 – 4ac
True

True True
=0 <0

Hai nghiệm
Nghiệm kép Vô nghiệm
phân biệt

Thông báo nghiệm

End
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 18
Giải thuật ứng dụng trong kinh doanh

Diễn đạt giải thuật

• Ví dụ 1: Giải thuật xác định n là số nguyên tố


– Bước 1: Ghi nhận n
– Bước 2: Nếu n ≤ 1  n không là nguyên tố  dừng
– Bước 3: Nếu n > 2, gán i  2
– Bước 4: Nếu i ≥ √n hay n chia hết cho i  bước 6
– Bước 5: Gán i  i+1, trở lại bước 4
– Bước 6:
• Nếu i > √n  n nguyên tố  dừng
• Ngược lại, n không là nguyên tố  dừng

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 19


Giải thuật ứng dụng trong kinh doanh

Diễn đạt giải thuật

• Ví dụ 2: Giải thuật tìm phần tử thứ n


của dãy số Fibonacci
 1 1 2 3 5 8 13 21(n=8)
– Bước 1: Ghi nhận n
– Bước 2: Nếu n=1 hay n=2  un=1  dừng
– Bước 3: Nếu n > 2, gán a1, b1, i1
– Bước 4: Gán ca+b, ab, bc
– Bước 5:
• Nếu i = n - 2  un=c  dừng
• Ngược lại i  i+1, quay lại bước 4

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 20


Giải thuật ứng dụng trong kinh doanh

Diễn đạt giải thuật

• Ví dụ 3: tìm phần tử lớn nhất trong mảng A


A[6]={2 3 5 4 6 10}
– Giải thuật TimMax(A, n)
Input: Mảng A, gồm n số nguyên
Output: Giá trị lớn nhất của A
Max  A[0]
for i  1 to n  1 do
if A[i]  Max then
Max  A[i]
return Max

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 21


Giải thuật ứng dụng trong kinh doanh

Các kiểu dữ liệu cơ bản


Các kiểu dữ liệu định sẵn trong C gồm các kiểu sau:

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 22


Giải thuật ứng dụng trong kinh doanh

Các kiểu dữ liệu cơ bản

Kiểu cơ bản chỉ lưu các giá trị đơn, không lưu
được các đối tượng dữ liệu phức hợp.
Đối tượng dữ liệu phức hợp là những đối tượng
dữ liệu được tạo nên từ nhiều kiểu dữ liệu cơ bản
hoặc kiểu dữ liệu phức hợp khác.
Trong thực tế các đối tượng dữ liệu ngoài việc lưu
trữ dữ liệu còn có các thao tác xử lý trên đối
tượng dữ liệu này nữa.
Khuyết điểm của kiểu cơ bản là không đáp ứng
được đầy đủ các yêu cầu lưu trữ dữ liệu thực tế, vì
nó chỉ có thể: Lưu giá trị đơn, không có được các
thao tác nghiệp vụ trên dữ liệu này.
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 23
Giải thuật ứng dụng trong kinh doanh

Các kiểu dữ liệu cơ bản

Ví dụ: Thực tế ta có dữ liệu là Nhân Viên, Mỗi


Nhân Viên gồm có các thông tin: Mã, Tên, năm
sinh, giới tính, ngày vào làm việc… Như vậy
không có 1 kiểu dữ liệu cơ sở nào mà đáp ứng
được đối tượng dữ liệu Nhân Viên này
Vì vậy ta cần tạo một kiểu dữ liệu phức hợp để có
thể đáp ứng yêu cầu này.

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 24


Giải thuật ứng dụng trong kinh doanh

Kiểu dữ liệu trừu tượng

 Các kiểu dữ liệu cơ sở không đủ để phản ánh tự


nhiên và đầy đủ bản chất của sự vật thực tế.
 Kiểu dữ liệu trừu tượng (Abstract Data Type) là
một mô hình toán kết hợp với các phép toán trên
mô hình này. Là sự trừu tượng các dữ liệu cơ bản
và các thủ tục (các phép toán….).
 Phải xây dựng các kiểu dữ liệu mới dựa trên việc
tổ chức, liên kết các thành phần dữ liệu có kiểu dữ
liệu đã được định nghĩa.
 Struct
 Class

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 25


Giải thuật ứng dụng trong kinh doanh

Kiểu dữ liệu có cấu trúc

• Trong nhiều trường hợp, các kiểu dữ liệu cơ sở


không đủ để phản ánh tự nhiên và đầy đủ bản chất
của sự vật thực tế, dẫn đến nhu cầu phải xây dựng
các kiểu dữ liệu mới dựa trên việc tổ chức, liên kết
các thành phần dữ liệu có kiểu dữ liệu đã được định
nghĩa. Những kiểu dữ liệu được xây dựng như thế
gọi là kiểu dữ liệu có cấu trúc.
• Đa số các ngôn ngữ lập trình đều cài đặt sẵn một số
kiểu có cấu trúc cơ bản như mảng, chuỗi, tập tin,
bản ghi... và cung cấp cơ chế cho lập trình viên tự
định nghĩa kiểu dữ liệu mới.

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 26


Giải thuật ứng dụng trong kinh doanh

Kiểu dữ liệu có cấu trúc

• Ví dụ: Để mô tả một đối tượng sinh viên, cần quan


tâm đến các thông tin sau:
- Mã sinh viên: chuỗi ký tự: string
- Tên sinh viên: chuỗi ký tự: string
- Ngày sinh: kiểu ngày tháng: DateTime
- Nơi sinh: chuỗi ký tự: string
- Điểm thi: số nguyên: int

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 27


Giải thuật ứng dụng trong kinh doanh

Kiểu dữ liệu có cấu trúc


• Các kiểu dữ liệu cơ sở cho phép mô tả một số thông tin như:
int Diemthi;
char masv[15];
char tensv[15];
char noisinh[15];
• Các thông tin khác đòi hỏi phải sử dụng các kiểu có cấu trúc
như:
Để thể hiện thông tin về ngày tháng năm cần phải xây dựng
một kiểu bản ghi
typedef struct tagDate{
char ngay;
char thang;
char thang;
}Date;
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 28
Giải thuật ứng dụng trong kinh doanh

Kiểu dữ liệu có cấu trúc


• Ta có thể xây dựng kiểu dữ liệu thể hiện thông tin về một
sinh viên:
typedef struct tagSinhVien {
char masv[15];
char tensv[45];
Date ngaysinh;
char noisinh[15];
int Diem thi;
} SinhVien;
• Giả sử đã có cấu trúc phù hợp để lưu trữ một sinh viên, nhưng
thực tế lại cần quản lý nhiều sinh viên, lúc đó nảy sinh nhu cầu
xây dựng kiểu dữ liệu mới... Mục tiêu của việc nghiên cứu cấu trúc
dữ liệu chính là tìm những phương cách thích hợp để tổ chức, liên
kết dữ liệu, hình thành các kiểu dữ liệu có cấu trúc từ những kiểu
dữ liệu đã được định nghĩa.
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 29
Giải thuật ứng dụng trong kinh doanh

Phân tích giải thuật

• Độ phức tạp không gian (Space complexity)


– Dung lượng bộ nhớ mà thuật toán đòi hỏi
• Độ phức tạp thời gian (Time complexity)
– Thời gian thực hiện thuật toán

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 30


Giải thuật ứng dụng trong kinh doanh

Phân tích thời gian thực hiện giải thuật

• Thời gian thực hiện giải thuật phụ thuộc


vào các yếu tố sau:
– Dữ liệu vào
– Tốc độ thực hiện các phép toán của máy tính
(phần cứng máy tính)
– Trình biên dịch

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 31


Giải thuật ứng dụng trong kinh doanh

Phân tích thời gian thực hiện giải thuật


• Sử dụng các công cụ toán học để đánh giá thời
gian chạy của giải thuật
• Gọi n là kích thước của dữ liệu vào, thời gian
thực hiện của giải thuật có thể biểu diễn là
một hàm của n: hàm T(n)

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 32


Giải thuật ứng dụng trong kinh doanh

Tiến trình phân tích thời gian thực hiện giải thuật

• Bước 1: Phân tích kích thước dữ liệu vào


• Bước 2: Phân tích (toán học) tìm ra giá trị
tốt nhất, trung bình, và giá trị xấu nhất cho
mỗi đại lượng cơ bản.

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 33


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật

• Từ bài toán đến chương trình

Thiết kế Lập trình #include


Bài toán …
thực tế

Giải thuật Chương trình

Kỹ thuật thiết kế giải •Ngôn ngữ lập


thuật: trình:
Chia để trị, quy hoạch •PASCAL, C/C++,
động, backtracking … JAVA, C#

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 34


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật


• Với một vấn đề đặt ra, làm thế nào để đưa ra thuật
toán giải quyết nó?
• Chiến lược thiết kế:
– Chia-để-trị (divide-and-conquer)
– Quy hoạch động (dynamic programming)
– Quay lui (backtracking): vét cạn
– Tham lam (greedy method): AI

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 35


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật

• Module hoá và việc giải quyết bài toán


– Chiến thuật chia để trị (divide-conquer):
Để thực hiện chiến thuật này, thường có hai cách
thiết kế:
1.Từ trên xuống (Top-Down Design)
2.Tinh chỉnh từng bước

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 36


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật


• Sau đây là lược đồ của kỹ thuật chia-để-trị:

DivideConquer (A,x) // tìm nghiệm x của bài toán A.



if (A đủ nhỏ)
Solve (A);
else 
Chia bài toán A thành các bài toán con
A1, A2,…, Am;
for (i = 1; i <= m ; i ++)
DivideConquer (Ai , xi);
Kết hợp các nghiệm xi của các bài toán con Ai (i=1, …, m)
để nhận được nghiệm x của bài toán A;

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 37


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật

• Tinh chỉnh từng bước:


– Biểu diễn ý tưởng bằng ngôn ngữ tự nhiên
– Cụ thể từng phần, thay đổi bằng ngôn ngữ
chương trình
– Cuối cùng ta có chương trình

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 38


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật

• Ví dụ: Bài toán sắp xếp một dãy n số, theo


thứ tự tăng dần
– Chọn số bé nhất trong n số để vào vị trí thứ 1
– Chọn số bé nhất trong n-1 số còn lại để vào vị trí thứ 2
– Chọn số bé nhất trong 2 số còn lại để vào vị trí thứ n-1

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 39


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật

•  For (i= 1, i <= n-1, i++)


{- Chọn số bé nhất trong các số
- Đổi chỗ cho xi
}
•  For (i= 1, i <= n-1, i++)
{- tg = x[i]
-So sánh tg với các số từ xi+1 -> xn . Nếu x[i] > các số đó
thì lại lấy số đó làm số tg
- đổi chổ x[i] và tg
}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 40


Giải thuật ứng dụng trong kinh doanh

Thiết kế giải thuật

for (i= 1; i <= n-1; i++)


for(j = i+1; j <=n; j++) {
If (x[j] < x[i])
{
Tg = x[i] ;
X[i] = x[j];
X[j] = tg ;
}
}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 41


Giải thuật ứng dụng trong kinh doanh

Độ phức tạp tính toán giải thuật


• Ví dụ:
– Giải thuật A, độ phức tạp thời gian Ta(n)
– Giải thuật B, độ phức tạp thời gian Tb(n)
– Khi n lớn, Ta(n) >> Tb(n). Có thể kết luận giải thuật A
chậm hơn giải thuật B.

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 42


Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật

• Ký hiệu O (Big-Oh): hàm f(n) và g(n), ta nói:


f(n) = Ο(g(n)), nếu tồn tại các hằng số dương c và no sao
cho f(n) ≤ cg(n) khi n ≥ no.
• Ký hiệu này dùng để chỉ chặn trên của một
hàm
• Ý nghĩa: Tốc độ tăng của hàm f(n) không lớn
hơn hàm g(n)

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 43


Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật


Cho f và g là hai hàm số nguyên, ta nói f(x) là O(g(x)) nếu tồn tại
hằng số C và k sao cho: |f(x)|  C|g(x)| với mọi x>k.
Ví dụ: Cho hàm f(x) =x2+3x+2 là O(x2).
Ta chứng minh f(x) là O(g(x))?

Thật vậy, khi x>2 thì x<x2 và 2<2x2


Do đó: x2+3x+2< x2+3x2 +2x2 x2+3x+2< 6x2
 |x2+3x+2|<6|x2| với mọi x>2
(Ở đây C=6, g(x)=x2, ta chọn được C=6 và k=2)
Kết luận: f(x)=x2+3x+2 là O(g(x))=x2 với mọi x>2

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 44


Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật

f(n) = 2n + 6
• Ví dụ : c g(n) = 4n

f(n) = 2n+6,
g(n) = n và c = 4 ,
n0=3
• f(n)= O(n)

g(n) = n

N0 = 3
n
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 45
Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật


• Định nghĩa Ω:
- f(n) = Ω(g(n)), nếu tồn tại các hằng số dương c
và no sao cho f(n) ≥ cg(n) khi n ≥ no
- f(n) = Ω(g(n))  g(n) = Ο(f(n))
• Định nghĩa 
f(n) = (g(n)), nếu tồn tại các hằng số dương c1,
c2 và n0 sao cho c1.g(n)  f(n)  c2. g(n) với mọi
n> n0

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 46


Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật

f ( n ) =O ( g ( n )) f ( n ) = ( g ( n ))
cg(n) f(n)

f(n)
cg(n)

n0 n0

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 47


Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật

f ( n ) =( g ( n ))
c2g(n)
f(n)

c1g(n)

n0

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 48


Giải thuật ứng dụng trong kinh doanh

Ký pháp để đánh giá độ phức tạp của giải thuật

• Ta nói độ phức tạp tính toán của giải thuật


có cấp f(n) nếu thỏa :
– T(n) = O(f(n)), và
– Nếu  g(n), mà T(n) = O(g(n)) thì f(n) = O(g(n)).

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 49


Giải thuật ứng dụng trong kinh doanh

Một số qui tắc về ký hiệu O lớn

• Nếu f1(n)=O(g1(n)) và f2(n)=O(g2(n))


– f1(n)+f2(n)=O(g1(n)+g2(n))=max(O(g1(n),g2(n))
– f1(n)*f2(n)=O(g1(n)*g2(n))
– logkn=O(n) với mọi hằng số k
• Nếu f(n) là một đa thức bậc k thì f(n) = O(nk),

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 50


Giải thuật ứng dụng trong kinh doanh

Một số qui tắc về ký hiệu O lớn


• f = O(f)
• f = O(g) và g = O(h) thì f = O(h)
• f = O(g) và h=O(r) thì fh = O(gr)
• f =O(g) và h=O(r) thì f+h = O(g+r)
• f =O(g) thì af = O(g) với mọi a>0.
• O(c)=O(1) , c là hằng số

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 51


Giải thuật ứng dụng trong kinh doanh

Một số qui tắc về ký hiệu O lớn


• Ví dụ:
– 2n là O(n)
– 3n + 5 là O(n) thay vì 3n + 5 là O(3n)
– 4n2 + 5n + 7  O(?)

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 52


Giải thuật ứng dụng trong kinh doanh

Xác định độ phức tạp tính toán


• T1(n) và T2(n) là thời gian thực hiện của hai giai đoạn
chương trình P1 và P2 mà T1(n) = O(f(n)); T2(n) =
O(g(n))
• Qui tắc tổng:
– Thời gian thực hiện đoạn P1 rồi P2 tiếp theo sẽ là T1(n) +
T2(n) = O(max(f(n),g(n))).
• Qui tắc nhân:
– Thời gian thực hiện P1 và P2 lồng nhau sẽ là : T1(n)T2(n) =
O(f(n)*g(n))

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 53


Giải thuật ứng dụng trong kinh doanh

Các quy tắc tổng quát


• Các phép gán, đọc, viết, goto là các phép toán sơ
cấp:
– Thời gian thực hiện là: O(1)
• Lệnh lựa chọn: if-else có dạng
if (<điều kiện>)
lệnh 1
else
lệnh 2

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 54


Giải thuật ứng dụng trong kinh doanh

Các quy tắc tổng quát


• Câu lệnh switch được đánh giá tương tự
như lệnh if-else.
• Các lệnh lặp: for, while, do-while
– Cần đánh giá số tối đa các lần lặp, giả sử đó là
L(n)
– Tiếp theo đánh giá thời gian chạy của mỗi lần
lặp là Ti(n), (i=1,2,..., L(n))
– Mỗi lần lặp, chi phí kiểm tra điều kiện lặp là
T0(n). L(n)

– Chí phí lệnh lặp là:  T0 n  + Ti n 


i =1

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 55


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
• Ví dụ 1. Mảng A các số thực, cỡ n, cần tìm
xem mảng có chứa số thực x không.
(1) i = 0;
(2) while (i < n && x != A[i])
A=5: gán
(3) i++; A==5: lệnh logic

 T(n)=O(n)
i=0 i=1 i=2 i=3 i=4
A= 5 8 2 1 5

Tìm x=5?

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 56


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
Case1: for (i=0; i<n; i++) (i=0,j=0,j=1,j=2…n)i=1j=0,j=1,j=2..j=n)
for (j=0; j<n; j++)
k++; O(n2)
Case 2: for (i=0; i<n; i++)
k++;
for (i=0; i<n; i++)
for (j=0; j<n; j++) O(n2)
k++;
Case 3: for (int i=0; i<n-1; i++)
for (int j=0; j<i; j++)
int k+=1; O(n2)

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 57


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
int MaxSubSum1(const int a[], int n) {
int maxSum=0;

for (int i=0; i<n; i++)


for (int j=i; j<n; j++) {
int thisSum=0;

for (int k=i; k<=j; k++)


thisSum+=a[k]; 3
O(n )
if (thisSum>maxSum)
maxSum=thisSum;
}
return maxSum;
}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 58


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
int MaxSubSum2(const int a[], int n) {
int maxSum=0;

for (int i=0; i<n; i++) {


thisSum=0;
for (int j=i; j<n; j++) {
thisSum+=a[j];

if (thisSum>maxSum)
2
T(n)=O(n )
maxSum=thisSum;
}
}
return maxSum;
}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 59


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
int MaxSubSum4(const int a[], int n) {
int maxSum=0, thisSum=0;

for (int j=0; j<n; j++) {


thisSum+=a[j];
if (thisSum>maxSum)
maxSum=thisSum;
else if (thisSum<0)

}
thisSum=0;
O(n)
return maxSum;
}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 60


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ

Sum=0
for (j=0;j<N;j++)
for (k=0;k<N*N;k++)
O(N3)
Sum++;

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 61


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
Ví dụ: sắp xếp dãy
void BubbleSort(int a[], int n)
{ int i,j,temp;
(1) for(i= 1; i<n; i++)
(2) for(j=n-1; j>=i;j--)
(3) if (a[j] < a[j-1]) {
(4) temp=a[j-1];
(5) a[j-1] = a[j];
(6) a[j] = temp;
}
}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 62


Giải thuật ứng dụng trong kinh doanh

Một số ví dụ
• Lệnh (3), (4), (5) và (6) đều tốn O(1)
• Vòng lặp (2) thực hiện (n-i) lần, mỗi lần O(1) do đó vòng lặp
(2) tốn O((n-i)*1) = O(n-i).
• Vòng lặp {1},i chạy từ 1 đến n-1, thời gian thực hiện của
vòng lặp (1)
• Độ phức tạp của giải thuật là
n 1
n(n  1)
T(n) =  (n  i) = = O(n 2 )
i =1 2

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 63


Giải thuật ứng dụng trong kinh doanh

Phân tích các hàm đệ quy


• Ví dụ: Hàm tính giai thừa
int Fact(int n)// VD: 4!=1x2x3x4=24
{
if (n <= 1)
return 1;
else return n * Fact(n-1);
}
• Với n <= 1, ta có T(1) = O(1).
• Với n > 1, ta có T(n) = 0(1) + T(n-1)

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 64


Giải thuật ứng dụng trong kinh doanh

Phân tích các hàm đệ quy


• Ta có quan hệ đệ quy sau:
– T(1) = O(1)
– T(n) = T(n-1) + O(1) với n > 1
• Thay các ký hiệu O(1) bởi các hằng số
dương a và b tương ứng, ta có
– T(1) = a
– T(n) = T(n-1) + b với n > 1

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 65


Giải thuật ứng dụng trong kinh doanh

Phân tích các hàm đệ quy


• Sử dụng các phép thế T(n-1) = T(n-2) + b,
T(n-2) = T(n-3) + b,..., ta có
T(n) = T(n-1) + b
= T(n-2) + 2b
= T(n-3) + 3b
...
= T(1) + (n-1)b
= a + (n-1)b
Từ đó, ta suy ra T(n) = O(n).

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 66


Giải thuật ứng dụng trong kinh doanh

Phân tích các hàm đệ quy


• Gọi T(n) là thời gian chạy của hàm đệ quy F
• Khi đó, thời gian chạy của các lời gọi hàm ở trong hàm
F sẽ là T(m) (với m < n)
• Trước hết, phải đánh giá thời gian chạy của hàm F
trên dữ liệu nhỏ nhất n = 1, giả sử T(1) = a (điều kiện
dừng)
• Sau đó, đánh giá thời gian chạy của các câu lệnh trong
thân của hàm F
• Tìm ra quan hệ đệ quy biểu diễn thời gian chạy của
hàm F thông qua lời gọi hàm

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 67


Giải thuật ứng dụng trong kinh doanh

Sự phân lớp của giải thuật


 Độ phức tạp
 O(1) độ phức tạp hằng số
 O(logn) độ phức tạp hàm logarit
 O(n) độ phức tạp hàm tuyến tính
 O(nlogn) độ phức tạp hàm nlogn
 O(nb) độ phức tạp hàm đa thức
 O(bn) độ phức tạp hàm mũ
 O(n!) độ phức tạp hàm giai thừa

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 68


Giải thuật ứng dụng trong kinh doanh

Sự phân lớp của giải thuật

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 69


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp

• Độ phức tạp tính toán của giải thuật trong


các trường hợp
• Xấu nhất
• Tốt nhất
• Trung bình

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 70


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


• Ví dụ 1: Thuật toán tìm kiếm tuần tự

int SequenceSearch(int x, int a[], int n){


for (int i=0;i<n;i++){
if (x==a[i]) return i;
}
return -1;
}
Tìm x=2 ? (i=04)
A[5]={5,9,2,4,8}

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 71


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


– Tốt nhất: phần tử đầu tiên là phần tử cần tìm, số lượng
phép so sánh là 2  T(n) ~ O(2)
– Xấu nhất: so sánh đến phần tử cuối cùng, số lượng phép
so sánh là 2n  T(n) ~ O(n)
– Trung bình: so sánh đến phần tử thứ i, cần 2i phép so
sánh, vậy trung bình cần
(2+4+6+…+2n)/n=2(1+2+…+n)/n=n+1
 T(n) ~ O(n)
int SequenceSearch(int x, int a[], int n){
for (int i=0;i<n;i++){
if (x==a[i])
return i;
}
return -1;
}
GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 72
Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


• Ví dụ 2: Tính độ phức tạp thuật toán sau

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 73


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


Trường hợp xấu nhất:

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 74


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


Trường hợp tốt nhất:

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 75


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


Trường hợp trung bình:

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 76


Giải thuật ứng dụng trong kinh doanh

Các trường hợp đánh giá độ phức tạp


Chú ý:

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 77


Giải thuật ứng dụng trong kinh doanh

Kiến thức toán học bổ trợ về các hàm chuỗi


N
S ( N ) = 1 + 2 +  + N =  i = N (1 + N ) / 2
i =1
N ( N + 1)( 2 N + 1) N 3
N
• Tổng các bình phương:  i = 2
 for large N
i =1 6 3

• Logarithms:
– xa = b  logx b = a

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 78


Giải thuật ứng dụng trong kinh doanh

Kiến thức toán học bổ trợ về các hàm chuỗi


N
N k +1

i =1
i 
k

| k +1|
for large N and k  -1

N
A N +1  1

i =0
A = i

A 1

– Đặc biệt khi A = 2


• 20 + 21 + 22 + … + 2N = 2N+1 - 1

GV: Nguyễn Văn Thọ - thonv@buh.edu.vn 79


TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HCM
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 2
ĐỆ QUY
& GIẢI THUẬT ĐỆ QUY
1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Khái niệm đệ quy, ưu nhược điểm


❖Giải thuật và chương trình đệ quy
❖Thiết kế giải thuật đệ quy
❖Một số giải thuật đệ quy phổ biến
❖Một số bài toán minh họa bằng giải thuật đệ quy

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui
❖Giải thuật đệ qui
▪ Giải bài toán bằng cách rút gọn liên tiếp bài toán
ban đầu thành bài toán cũng tương tự nhưng có
dữ liệu đầu vào nhỏ hơn.
▪ Ví dụ
• n! có thể được định nghĩa bằng cách qui nạp như sau:
• 0! = 1,
• n! = n*(n-1)!, với mọi n > 0.
→Bài toán tính N! bây giờ thành tính N*(N-1)!

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 3


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui
➢ Hàm (phương thức) được gọi là đệ qui nếu trong
quá trình thực hiện nó tự gọi đến chính mình.
➢ Đệ qui trực tiếp : Lời gọi có thể nằm bên trong hàm
(phương thức).
➢ Đệ qui gián tiếp : Nếu hàm (phương thức) gọi tới
hàm (phương thức) khác, mà hàm (phương thức)
này lần lượt gọi tới hàm (phương thức) ban đầu.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui

➢ Như đã biết, một thuật toán được đòi hỏi phải thỏa
mãn các tính chất:
✓ Tính xác định.
✓ Tính hữu hạn (tính dừng).
✓ Tính đúng đắn.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 5


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui

➢ Do tính chất của thuật toán là sau một số hữu hạn


các phép toán thì thuật toán kết thúc, vì vậy thuật
toán đệ qui phải gồm có 2 phần:
– Phần đệ qui
– Phần không đệ qui (phần cơ sở -phần làm dừng
tính đệ qui)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui

➢ Phần cơ sở gồm các trường hợp không cần thực


hiện lại giải thuật, tức là các trường hợp dừng mà ta
có thể trực tiếp giải quyết được bài toán (hay
không có yêu cầu gọi đệ qui).
➢ Ví dụ : tính N! thì trường hợp n=1 thì không cần
tính nữa gọi là phần cơ sở

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 7


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui

➢ Phần đệ qui là phần trong giải thuật có yêu cầu gọi


đệ qui, tức là yêu cầu thực hiện lại giải thuật ở cấp
độ thấp hơn.
➢ Trong phần đệ qui, yêu cầu gọi đệ qui thường được
đặt trong một điều kiện kiểm tra việc gọi đệ qui.
➢ Ví dụ : tính N! thì phần gọi đệ qui là những giá trị
(N-1)! ,(N-2)! …. Và thường được đặt trong điều
kiện N>1

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui

➢ Ưu điểm; của giải thuật đệ qui là ngắn gọn. Nó có


khả năng định nghĩa một tập hợp rất lớn các đối
tượng bằng một số các câu lệnh hữu hạn.
➢ Khuyết điểm: không xác định được bước lặp, bước
thực hiện của giải thuật
➢ Nếu có thể thay thế giải thuật đệ qui bằng một giải
thuật khác không tự gọi chúng (không đệ qui) giải
thuật này được gọi là giải thuật khử đệ qui.
➢ Chỉ khi nào không thể dùng giải thuật lặp ta mới
nên sử dụng thuật toán đệ qui

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 9


Khoa Hệ Thống Thông Tin Quản lý

Cơ chế hoạt động của Đệ qui

➢ Hoạt động theo cơ chế LIFO (LAST IN FIRST OUT)


➢ Dùng stack để lưu vết dữ liệu và chỉ thị lệnh

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Khoa Hệ Thống Thông Tin Quản lý

Cơ chế hoạt động của Đệ qui

➢ Minh họa Đệ qui chuyển cơ số 10 sang cơ số 2

void H10toH2(int n)
{
if (n <= 0) return;
int t = n % 2;
H10toH2(n / 2);
H10toH2(11);
printf(“%d”,t);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 11


Khoa Hệ Thống Thông Tin Quản lý

Cơ chế hoạt động của Đệ qui

➢ Giải Thuật đệ qui tính giai thừa của một số tự


nhiên.
• Input : số tự nhiên n.
• Output : giaithua (n) bằng n!.
• Giải Thuật Đệ Qui:
– 1. if (n=1) || (n=0) return 1 //n!= 1
– 2. return giaithua(n-1) * n; // Tính (n-1)! rồi nhân với n

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 12


Khoa Hệ Thống Thông Tin Quản lý

Cơ chế hoạt động của Đệ qui

➢ Giải Thuật đệ qui tính giai thừa của một số tự


nhiên.
int Giaithua(int n)
{
if(n==1)||(n==0) { return 1;}
return Giaithua(n-1)*n;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 13


Khoa Hệ Thống Thông Tin Quản lý

Cơ chế hoạt động của Đệ qui

⚫ Tính 4!

24

Giaithua(4) 4*6=24

3*2=6
4*Giaithua(3)

2*1=2
3*Giaithua(2)

1
2*Giaithua(1)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 14


Khoa Hệ Thống Thông Tin Quản lý

Cơ chế hoạt động của Đệ qui long Fibonaci (int n)


{
➢ Minh họa Đệ qui Fibonacci if(n==0 || n==1)
5 return 1;
return Fibonaci(n-1) +
3 Fibonaci(n-2);
4
}
1
3 2 2
1

2 1 1 0 1 0

1 1 1 1 1
1 0

1 1
Kết quả =8

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 15


Khoa Hệ Thống Thông Tin Quản lý

Hàm đệ qui

➢ Phân loại đệ qui


*Đe qui tuyé n tính.
*Đe qui nhi phân.
*Đe qui phi tuyé n.
*Đe qui tương hõ .

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 16


Khoa Hệ Thống Thông Tin Quản lý

Đệ qui tuyến tính

Trong thân hàm có duy nhất một lời gọi hàm gọi lại chính nó
một cách tường minh:
<Kiểu dữ liệu hàm> TenHam (<danh sách tham số>)
{
if (điều kiện dừng)
{
...
//Trả về giá trị hay kết thúc công việc
}
//Thực hiện một số công việc (nếu có)
. . . TenHam (<danh sách tham số>);
//Thực hiện một số công việc (nếu có)
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 17


Khoa Hệ Thống Thông Tin Quản lý

Đệ qui tuyến tính

Ví dụ:
Tính S (n) = 1 + 2 + 3 + L + n
- Điều kiện dừng: S(0) = 0.
- Qui tắc (công thức) tính: S(n) = S(n-1) + n.
long TongS (int n)
{
if(n==0)
return 0;
return ( TongS(n-1) + n );
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 18


Khoa Hệ Thống Thông Tin Quản lý

Đệ qui nhị phân


Trong than củ a hà m có 2 lời goi hà m goi lai chính nó
mot cá ch tường minh:
<Kiẻ u dữ lieu hà m> TenHam (<danh sá ch tham só >)
{
if (điè u kien dừng)
{
...
//Trả vè giá tri hay ké t thú c cong viec
}
//Thưc hien mot só cong viec (né u có )
. . .TenHam (<danh sá ch tham só >); //Giả i quyé t vá n đè nhỏ hơn
//Thưc hien mot só cong viec (né u có )
. . . TenHam (<danh sá ch tham só >); //Giả i quyé t vá n đè cò n lai
//Thưc hien mot só cong viec (né u có )
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 19
Khoa Hệ Thống Thông Tin Quản lý

Đệ qui nhị phân


Ví du: Tính só hang thứ n củ a dã y Fibonaci đươc đinh
nghĩa như sau:
f1 = f0 =1 ;
fn = fn-1 + fn-2 ;

Điều kiện dừng: f(0) = f(1) = 1.


long Fibonaci (int n)
{
if(n==0 || n==1)
return 1;
return Fibonaci(n-1) + Fibonaci(n-2);
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 20
Khoa Hệ Thống Thông Tin Quản lý

Đệ qui phi tuyến


Trong than củ a hà m có lời goi hà m goi lai chính nó đươc đat
ben trong vò ng lap:
<Kiẻ u dữ lieu hà m> TenHam (<danh sá ch tham só >)
{
for (int i = 1; i<=n; i++)
{
//Thưc hien mot só cong viec (né u có )
if (điè u kien dừng)
{ ...
//Trả vè giá tri hay ké t thú c cong viec
}
else
{ //Thưc hien mot só cong viec (né u có )
TenHam (<danh sá ch tham só >);
}
}
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 21
Khoa Hệ Thống Thông Tin Quản lý

Đệ qui phi tuyến


Ví du: Tính só hang thứ n củ a dã y {Xn} đươc đinh nghĩa như
sau:
X0 =1 ;
Xn = n2X0 + (n-1)2X1 + … + 12Xn-1 ;
Điều kiện dừng:X(0) = 1.
long TinhXn (int n)
{
if(n==0)
return 1;
long s = 0;
for (int i=1; i<=n; i++)
s = s + i * i * TinhXn(n-i);
return s;
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 22
Khoa Hệ Thống Thông Tin Quản lý

Đệ qui tương hỗ

Trong than củ a hà m nà y có lời goi hà m đé n hà m kia
và trong than củ a hà m kia có lời goi hà m tới hà m nà y.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 23


Khoa Hệ Thống Thông Tin Quản lý

Đệ qui tương hỗ
<Kiẻ u dữ lieu hà m> TenHam2 (<danh sá ch tham só >);
<Kiẻ u dữ lieu hà m> TenHam1 (<danh sá ch tham só >)
{
//Thưc hien mot só cong viec (né u có )
…TenHam2 (<danh sá ch tham só >);
//Thưc hien mot só cong viec (né u có )
}
<Kiẻ u dữ lieu hà m> TenHam2 (<danh sá ch tham só >)
{
//Thưc hien mot só cong viec (né u có )
…TenHam1 (<danh sá ch tham só >);
//Thưc hien mot só cong viec (né u có )
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 24


Khoa Hệ Thống Thông Tin Quản lý

Đệ qui tương hỗ
Ví du: Tính só hang thứ n củ a hai dã y {Xn}, {Yn} đươc đinh nghĩa như sau:
X0 =Y0 =1 ;
Xn = Xn-1 + Yn-1; (n>0)
Yn = n2Xn-1 + Yn-1; (n>0)
- Điều kiện dừng:X(0) = Y(0) = 1.
long TinhXn (int n)
{
if(n==0)
return 1;
return TinhXn(n-1) + TinhYn(n-1);
}
long TinhYn (int n)
{
if(n==0)
return 1;
return n*n*TinhXn(n-1) + TinhYn(n-1);
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 25
Khoa Hệ Thống Thông Tin Quản lý

Khử đệ qui

➢ Những giải thuật có thể cài đặt được bằng các


vòng lặp thay thế cho đệ qui thì nên dùng vòng
lặp, vì đệ qui rất tốn bộ nhớ, xử lý chậm.
❖ Hãy khử đệ qui tính giai thừa
❖ Hãy khử đệ qui tính số fibonacci

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 26


Khoa Hệ Thống Thông Tin Quản lý

Bài tập rèn luyện


➢ Hãy viết giải thuật và minh họa từng bước quá trình chạy
Đệ qui của bài toán Tháp Hà Nội, luật chơi được mô tả:
Trò chơi này gồm một bộ các đĩa kích thước khác
nhau, có lỗ ở giữa, nằm xuyên trên ba cái cọc. Bài
toán đố bắt đầu bằng cách sắp xếp các đĩa theo
trật tự kích thước vào một cọc sao cho đĩa nhỏ
nhất nằm trên cùng, tức là tạo ra một dạng hình
nón. Yêu cầu của trò chơi là di chuyển toàn bộ số
đĩa sang một cọc khác, tuân theo các quy tắc sau:
✓ Một lần Chỉ có 3 cột để di chuyển.
✓ Chỉ được di chuyển một đĩa trên cùng(không
được di chuyển đĩa nằm giữa).
✓ Một đĩa chỉ có thể được đặt lên một đĩa lớn
hơn (không nhất thiết hai đĩa này phải có kích
thước liền kề, tức là đĩa nhỏ nhất có thể nằm
trên đĩa lớn nhất).

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 27


Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội

Cần chuyển N đĩa từ cột A sang cột C,


với B làm cột tạm.
Ý tưởng đệ qui:
Nếu đã biết cách chuyển N-1 đĩa từ
cột A sang cột B ➔ ta chuyển Đĩa
thứ N từ cột A sang cột C ➔rồi
chuyển N-1 đĩa từ cột B sang cột C.
➔Giải thuật không còn đệ qui khi
chỉ có 1 Đĩa, vì lúc này ta chuyển
trực tiếp từ cột A qua cột C luôn.

Độ phức tạp chính xác: 2n-1


GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 28
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội Nếu cột A chỉ có 1 đĩa

A B C

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 29


Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội Nếu cột A chỉ có 2 đĩa

A B C

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 30


Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội Nếu cột A chỉ có 3 đĩa

A B C

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 31


Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội


private void btnMove_Click(object sender, EventArgs e)
{
lblChiTiet.Text = "";
int n = int.Parse(txtDia.Text);
move(n, 'A', 'B', 'C');
}
private void move(int n,char A,char B,char C)
{
if(n==1)
{
lblChiTiet.Text += A + "==>"+C+"\n";
}
else
{
move(n - 1, A, C, B);
lblChiTiet.Text += A + "==>" + C + "\n";
move(n - 1, B, A, C);
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 32


Khoa Hệ Thống Thông Tin Quản lý

Diễn giải từng bước chạy


Minh họa Đệ qui Tháp Hà Nội
theo cơ chế LIFO khi n=3
Di chuyển 3 đĩa từ cột A sang cột C,
với cột B làm cột trung gian: 0 move(3, 'A', 'B', 'C');
0 move(3, 'A', 'B', 'C'); n=3,
1 move(int n,char A,char B,char C) 1 n=3, A='A', B='B', C='C' A='A'
{ B='B'
4 move(n - 1, A, C, B); C='C'
2 if(n==1) {
stack
3 Chuyển: A ==> C move(2, 'A', 'C', 'B');
} Khi gọi đệ qui, chỉ
thị lệnh từ số 5 và
else { các giá trị của n=2,
biến local sẽ được A='A'
4 move(n - 1, A, C, B);
đưa vào Stack B='C'
5 Chuyển: A ==>C C='B'
6 move(n - 1, B, A, C); 1 n=2, A='A', B='C', C='B'
n=3,
} A='A'
4 move(n - 1, A, C, B);
} B='B'
C='C'
move(1, 'A', 'B', 'C');
stack
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 33
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội


Di chuyển 3 đĩa từ cột A sang cột C, move(1, 'A', 'B', 'C');
với cột B làm cột trung gian: n=2,
0 move(3, 'A', 'B', 'C'); A='A'
1 n=1, A='A', B='B', C='C' B='C'
1 move(int n,char A,char B,char C) C='B'
{
3 Chuyển 1 đĩa từ A ==> C n=3,
2 if(n==1) {
A='A'
3 Chuyển: A ==> C Chuyển 1 đĩa từ 'A' ==> 'C'
Khi thực hiện xong lệnh 3 tức là hết B='B'
} đệ qui, lúc này hệ thống sẽ gọi C='C'
else { Stack ra (lấy thông số trên cùng). stack
Lúc này chỉ thị lệnh hoạt động từ
4 move(n - 1, A, C, B); lệnh số 5.
5 Chuyển: A ==>C 5 Chuyển 1 đĩa từ A ==> C
6 move(n - 1, B, A, C); n=3,
Chuyển 1 đĩa từ 'A' ==> 'B' A='A'
}
B='B'
} 6 move(n - 1, B, A, C) C='C'
stack
move(1, 'C', 'A', 'B');
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 34
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội


move(1, 'C', 'A', 'B');
Di chuyển 3 đĩa từ cột A sang cột C,
với cột B làm cột trung gian: n=3,
0 move(3, 'A', 'B', 'C'); A='A'
1 n=1, A='C', B='A', C='B' B='B'
1 move(int n,char A,char B,char C)
C='C'
{
3 Chuyển 1 đĩa từ A ==> C stack
2 if(n==1) {
3 Chuyển: A ==> C Chuyển 1 đĩa từ 'C' ==> 'B'
Khi thực hiện xong lệnh 3 tức là hết
} đệ qui, lúc này hệ thống sẽ gọi
else { Stack ra. Lúc này chỉ thị lệnh hoạt
động từ lệnh số 5.
4 move(n - 1, A, C, B);
5 Chuyển: A ==>C 5 Chuyển 1 đĩa từ A ==> C
6 move(n - 1, B, A, C);
Chuyển 1 đĩa từ 'A' ==> 'C'
}
} 6 move(n - 1, B, A, C)
stack
move(2, 'B', 'A', 'C');
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 35
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội


Di chuyển 3 đĩa từ cột A sang cột C,
move(2, 'B', 'A', 'C');
với cột B làm cột trung gian:
0 move(3, 'A', 'B', 'C');
1 n=2, A='B', B='A', C='C' n=2,
1 move(int n,char A,char B,char C)
A='B'
{ B='A'
4 move(n - 1, A, C, B);
2 if(n==1) { C='C'
3 Chuyển: A ==> C move(1, 'B', 'C', 'A'); stack
} Khi gọi đệ qui, chỉ
thị lệnh từ số 5 và
else { các giá trị của
4 move(n - 1, A, C, B); biến local sẽ được
đưa vào Stack
5 Chuyển: A ==>C
6 move(n - 1, B, A, C); 1 n=1, A='B', B='C', C='A'

}
3 Chuyển 1 đĩa từ A ==> C
}

Chuyển 1 đĩa từ 'B' ==> 'A'


GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 36
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội


Khi thực hiện xong lệnh 3 tức là hết
Di chuyển 3 đĩa từ cột A sang cột C,
đệ qui, lúc này hệ thống sẽ gọi n=2,
với cột B làm cột trung gian:
Stack ra. Lúc này chỉ thị lệnh hoạt A='B'
0 move(3, 'A', 'B', 'C');
động từ lệnh số 5.
1 move(int n,char A,char B,char C) B='A'
5 Chuyển 1 đĩa từ A ==> C C='C'
{
2 if(n==1) { stack
Chuyển 1 đĩa từ 'B' ==> 'C'
3 Chuyển: A ==> C
6 move(n - 1, B, A, C)
}
else {
move(1, 'A', 'B', 'C');
4 move(n - 1, A, C, B);
5 Chuyển: A ==>C 1 n=1, A='A', B='B', C='C'
6 move(n - 1, B, A, C);
}
3 Chuyển 1 đĩa từ A ==> C
}
Chuyển 1 đĩa từ 'A' ==> 'C' stack
Có tổng cộng 23-1=7; số đĩa=3 Stack rỗng+ n=1➔kết thúc toàn bộ giải thuật đệ qui.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 37
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội

A B C
Lần 4: 'A' ==> 'C'
A B C

A B C A B C
Lần 1: 'A' ==> 'C' Lần 5:'B' ==> 'A'

A B C A B C
Lần 2: 'A' ==> 'B' Lần 6: 'B' ==> 'C'

A B C A B C
Lần 3: 'C' ==> 'B' Lần 7:‘A' ==> ‘C'
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 38
Khoa Hệ Thống Thông Tin Quản lý

Minh họa Đệ qui Tháp Hà Nội Nếu cột A chỉ có 4 đĩa


(Sinh viên Tự làm)

A B C

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 39


TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HCM
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 3

DANH SÁCH - LIST


1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Giới thiệu
❖Phân loại: Danh sách đặc & danh sách liên kết
❖Khái niệm về danh sách liên kết
❖Sự khác biệt giữa danh sách liên kết và mảng
❖Một số loại danh sách liên kết thường gặp
❖Các thao tác trên danh sách liên kết đơn
❖Ngăn xếp
❖Hàng đợi

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về danh sách

❖Danh sách là tập hợp các phần tử có kiểu dữ liệu


xác định và giữa chúng có một mối quan hệ nào đó
❖Số phần tử của danh sách gọi là chiều dài của DS
❖Danh sách có chiều dài bằng 0 gọi là DS rỗng
Các phép toán:
- Tạo mới danh sách
- Thêm một phần tử vào danh sách
- Tìm kiếm 1 phần tử trong danh sách
- Loại bỏ 1 phần tử khỏi danh sách
- Cập nhật 1 phần tử trong danh sách
- Sắp xếp các phần tử trong danh sách
- Kết hợp các danh sách thành 1 danh sách
- Hủy danh sách…
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 3
Khoa Hệ Thống Thông Tin Quản lý

Phân loại

❖Danh sách đặc


❖Danh sách liên kết

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm về danh sách đặc


• Danh sách đặc là danh sách mà không gian bộ nhớ
lưu trữ các phần tử được đặt liên tiếp nhau trong bộ
nhớ.
• Mảng là cấu trúc bao gồm các thành phần cùng kiểu
dữ liệu, mỗi thành phần được gọi là phần tử và xác
định qua chỉ số.
Trong C/C++ khai báo:
elem a[spt];
Trong đó elem là kiểu phần tử (element type); spt
là số phần tử.
Ví dụ:
int a[10]; //mảng a gồm 10 phần tử kiểu int
float b[20]; //mảng b gồm 20 phần tử kiểu float
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 5
Khoa Hệ Thống Thông Tin Quản lý

Khái niệm về danh sách đặc

• Mảng được quản lý bằng một địa chỉ trong bộ nhớ


máy tính và các phần tử được bố trí tuần tự liên
tiếp theo chỉ số
0 1 2 9
a

• Chính vì vậy dãy dữ liệu lưu trữ trong mảng còn


được gọi là danh sách đặc

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Khoa Hệ Thống Thông Tin Quản lý

Ưu và nhược của danh sách đặc

• Ưu điểm
– Mật độ sử dụng 100%
– Dễ dàng truy xuất đến từng phần tử
• Nhược điểm
– Độ phức tạp thuật toán thêm/bớt phần tử vào/ra danh sách
là khá cao T(n)max=O(n)
– Lãng phí khi trong danh sách có nhiều phần tử cùng giá trị

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 7


Khoa Hệ Thống Thông Tin Quản lý

Khai báo cấu trúc danh sách kề

#define MAXLIST 100


typedef struct DanhSachKe{
int num;
int nodes[MAXLIST];
}List;

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Khởi tạo danh sách


void Init(List &plist){
plist.num=0;
}
• Xác định số nút
int ListSize(List plist){
return plist.num;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 9


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Kiểm tra danh sách rỗng


int IsEmpty(List plist){
return (plist.num==0);
}
• Kiểm tra danh sách đầy
int IsFull(List plist){
return (plist.num==MAXLIST);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Truy xuất một phần tử trong danh sách


int Retrieve(List plist, int pos){
if(pos<0 || pos>=ListSize(plist))
{ printf("Vi tri %d khong hop le",pos); return 0;}
else
{ if(IsEmpty(plist))
printf("danh sach bi rong");
else
return plist.nodes[pos];
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 11


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Thêm một phần tử vào danh sách


void Insert(List &plist, int pos, int x)
{ int i;
if (pos<0||pos>plist.num){ printf("Vi tri chen khong hop le !"); return }
else{ if(IsEmpty(plist) ){
printf("Danh sach rong !");
return; }
else {
for (i=plist.num-1;i>pos;i-- )
{ plist.nodes[i]=plist.nodes[i-1]; }
plist.nodes[pos]=x;
plist.num++; }
}
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 12
Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Xóa một phần tử ra khỏi danh sách


int Remove(List &plist, int pos){
int i;
int x;
if(pos <0 || pos>=ListSize(plist))
printf("\n Vi tri xoa khong phu hop");
else{
if(IsEmpty(plist)) printf("\n Danh sach rong");
else{
x=plist.nodes[pos];
for(i=pos;i<ListSize(plist)-1;i++){
plist.nodes[i]=plist.nodes[i+1];
}
plist.num--;
return x;
}
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 13


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Sắp xếp danh sách


void SelectionSort(List &plist){
int i,j,vitrimin,min;
for(i=0;i<plist.num-1;i++){
min=plist.nodes[i];
vitrimin=i;
for(j=i+1;j<plist.num;j++){
if(min >plist.nodes[j]){
min=plist.nodes[j];
vitrimin=j;
}
}
plist.nodes[vitrimin]=plist.nodes[i];
plist.nodes[i]=min;
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 14


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

• Tìm kiếm 1 phần tử trong danh sách


int Search(List plist, int x){
int vitri=0;
while(plist.nodes[vitri]!=x && vitri<plist.num) vitri++;
if(vitri==plist.num) return -1;
return vitri;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 15


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách đặc sử dụng mảng

Bài tập
Viết chương trình quản lý sinh viên cài đặt bằng
danh sách đặc. Chương trình gồm các chức năng:
- Thêm danh sách SV
- Thêm 1 SV vào danh sách
- Xóa 1 SV khỏi danh sách
- Hiệu chỉnh sinh viên
- Sắp xếp danh sách SV theo mã sinh viên
- Tìm kiếm SV theo mã SV
- Xóa toàn bộ danh sách SV
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 16
Khoa Hệ Thống Thông Tin Quản lý

DANH SÁCH LIÊN KẾT

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 17


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm về danh sách liên kết

❖Danh sách liên kết là một cấu trúc dữ liệu dùng để


lưu trữ tập các phần tử rời rạc có thể co giãn một
cách linh động.
❖Kích thước của danh sách liên kết không cần định
nghĩa trước, nó tự động thay đổi khi số phần tử
trong danh sách thay đổi.
❖Không giới hạn số lượng phần tử
❖Dễ dàng thực hiện thao tác: thêm, sửa , xóa
❖Truy xuất dữ liệu kiểu tuần tự

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 18


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm về danh sách liên kết

❖Trong danh sách liên kết, mỗi một Node (phần tử)
thường có ít nhất 2 thông số: Giá trị của Node và
mối liên kết tới Node khác.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 19


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm về danh sách liên kết

❖Để quản lý danh sách liên kết ta thường quản lý


Node đầu, hoặc quản lý cả Node đầu và Node cuối
pHead

8 pNext 9 pNext 5 pNext NULL

pHead
pTail

8 pNext 9 pNext 5 pNext NULL


GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 20
Khoa Hệ Thống Thông Tin Quản lý

Sự khác biệt giữa danh sách liên kết và mảng


Mảng Danh sách liên kết
Phải biết trước số lượng phần Không cần biết trước, không
tử, bị giới hạn bởi số lượng ban bị giới hạn số lượng phần tử,
đầu cấp phát tự động thay đổi kích thước
Truy xuất ngẫu nhiên hoặc truy Chỉ truy xuất tuần tự
xuất tuần tự
Khó xóa phần tử trong mảng Dễ dàng xóa phần tử trong
danh sách
Khó thêm thêm phần tử Dễ thêm phần tử
Dễ sắp xếp Khó sắp xếp
Dễ tìm kiếm Dễ tìm kiếm

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 21


Khoa Hệ Thống Thông Tin Quản lý

Một số loại danh sách liên kết thường gặp


❑ Danh sách liên kết đơn: Mỗi phần tử liên kết với phần tử
đứng sau nó trong danh sách

pHead
pTail

8 pNext 9 pNext 5 pNext NULL

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 22


Khoa Hệ Thống Thông Tin Quản lý

Một số loại danh sách liên kết thường gặp

❑ Danh sách liên kết đôi: mỗi phần tử liên kết với các phần
tử đứng trước và sau nó trong danh sách

pHead pTail

NULL pPre
pPre 8 pNext pPre 9 pNext pPre 5 pNext 10 pNext
NULL

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 23


Khoa Hệ Thống Thông Tin Quản lý

Một số loại danh sách liên kết thường gặp


❑ Danh sách liên kết vòng : Phần tử cuối danh sách liên kết
với phần tử đầu danh sách:

A D I M N W

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 24


Khoa Hệ Thống Thông Tin Quản lý

Các thao tác trên danh sách liên kết đơn

❖Tạo cấu trúc dữ liệu cho danh sách liên kết


❖Thêm Node : Đầu, cuối, giữa danh sách
❖Duyệt danh sách
❖Xóa Node: Đầu, cuối, giữa danh sách
❖Tìm kiếm
❖Sửa node theo điều kiện
❖Sắp xếp

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 25


Khoa Hệ Thống Thông Tin Quản lý

Tạo cấu trúc dữ liệu cho danh sách liên kết

❖Tạo cấu trúc Node


Khai báo mỗi cấu trúc là một mẫu tin có hai trường
info và trường next:
- Trường info: chứa nội dung của nút.
- Trường next: là con trỏ chỉ nút, dùng để chỉ đến nút
kế tiếp trong danh sách liên kết.

typedef struct node{


int info;
node* next;
}Node;
typedef Node* NODEPTR;
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 26
Khoa Hệ Thống Thông Tin Quản lý

Tạo cấu trúc dữ liệu cho danh sách liên kết

❖Khởi tạo danh sách liên kết đơn pHead


void Init(NODEPTR &phead){
phead=NULL; NULL
} Size
=0 pTail

❖Kiểm tra danh sách có rỗng hay không


int IsEmpty(NODEPTR phead){
return (phead==NULL);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 27


Khoa Hệ Thống Thông Tin Quản lý

Tạo cấu trúc dữ liệu cho danh sách liên kết

❖Tạo node trong danh sách liên kết đơn


NODEPTR CreateNode(int x){
NODEPTR p=new Node;
p->info=x;
p->next=NULL;
return p;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 28


Khoa Hệ Thống Thông Tin Quản lý

Thêm node vào đầu danh sách

• Thêm một nút p vào đầu danh sách


– Nếu Danh sách rỗng Thì
• Gán: pHead = p;
– Ngược lại
• p->Next = pHead;
• pHead = p;

pHead
A B C D E NULL

X
p

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 29


Khoa Hệ Thống Thông Tin Quản lý

Thêm node vào đầu danh sách


void InsertFirst(NODEPTR &phead, int x){
NODEPTR p=CreateNode(x);
if(phead==NULL)
phead=p;
else
{
p->next=phead;
phead=p;
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 30


Khoa Hệ Thống Thông Tin Quản lý

Thêm node vào cuối danh sách


• Chèn nút p vào cuối
– Nếu Danh sách rỗng Thì
• Gán: pHead = p;
– Ngược lại
• Gán ptemp = pHead;
• Đi về nút cuối của danh sách
(while (ptemp->next != NULL) ptemp = ptemp->next;)
• ptemp->pNext = p;

pHead
A B C D E
ptemp
X p

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 31


Khoa Hệ Thống Thông Tin Quản lý

Thêm node vào cuối danh sách


void InsertLast(NODEPTR &phead, int x){
NODEPTR tam=CreateNode(x);
NODEPTR p = phead;
if (phead==NULL)
phead=tam;
else
{
NODEPTR ptemp=phead;
while (ptemp->next!=NULL)
ptemp = ptemp->next;

ptemp->next=tam;
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 32


Khoa Hệ Thống Thông Tin Quản lý

Thêm nút có nội dung x vào sau nút q

– Nếu (q != NULL)
• p=CreateNode(x)
• p>next = q->next;
• q->next = p ;
– Ngược lại: q = p;
q
pHead
A B C D E

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 33


Khoa Hệ Thống Thông Tin Quản lý

Thêm nút có nội dung x vào sau nút q


void InsertAfter (NODEPTR q, int x){
NODEPTR tam;
if(q!=NULL){
tam=CreateNode(x);
tam->next=q->next;
q->next=tam;
}
} q
pHead
A B C D E

p
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 34
Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút trong danh sách

• Xóa nút đầu danh sách


– Nếu (pHead != NULL) thì
• p = pHead; // p là nút cần xóa
• pHead = pHead->pNext;
• delete p;

p
pHead
A B X Z Y

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 35


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút trong danh sách

• Xóa nút đầu danh sách

p
pHead
A B X Z Y

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 36


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút trong danh sách


• Xóa một nút đứng sau p
– Nếu (p!= NULL) thì
• q = p->Next; // q là nút cần xóa
• p->Next = q->Next; // tách q ra khỏi ds
• delete q; // Giải phóng q
– Ngược lại:
• Xóa nút đầu danh sách

p q
pHead
A B C D E

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 37


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút trong danh sách


• Xóa một nút đứng sau p

p q
pHead
A B C D E

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 38


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút trong danh sách


• Xóa một nút có khóa x
– Tìm nút p có khóa k và phần tử q đứng trước nó
– Nếu (p!= NULL) // tìm thấy x
• xóa p đứng sau nút q;
– Ngược lại
– Báo không có x; Xóa nút có
khóa là X

q
pHead
A B X Z Y

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 39


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút trong danh sách


• Xóa một nút có khóa x
void DeleteX(NODEPTR &pHead, int x)
{
NODEPTR q;
NODEPTR p = pHead;
while ((p != NULL) && (p->info != x))
{
q = p;
p = p->next;
}
if (q != NULL)
DeleteAfter(q);
else Xóa nút có
DeleteFirst(q); khóa là X
}
q
pHead
A B X Z Y

p
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 40
Khoa Hệ Thống Thông Tin Quản lý

Duyệt danh sách

p = pHead;
– Trong khi chưa hết danh sách
• Xử lý nút p ;
• p= p->pNext;

pHead
A B C D E

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 41


Khoa Hệ Thống Thông Tin Quản lý

Duyệt danh sách

void ShowList(NODEPTR phead){


NODEPTR p=phead;
if(p==NULL)
printf("\n Danh sach bi rong");
while(p!=NULL){
printf("%5d",p->info);
p=p->next;
}
}
pHead
A B C D E

P
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 42
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm trên danh sách


➢ Danh sách liên kết đòi hỏi truy xuất tuần tự, do đó chỉ có thể
áp dụng thuật toán tìm tuyến tính để xác định phần tử trong
xâu có khoá x. Sử dụng một con trỏ phụ trợ p để lần lượt trỏ
đến các phần tử trong xâu. Thuật toán được thể hiện như sau
✓ Bước 1:
p = Head; //Cho p trỏ đến phần tử đầu danh sách
✓ Bước 2:
Trong khi (p != NULL) và (p->data != x ) thực hiện:
B21 : p=p->Next;// Cho p trỏ tới phần tử kế
✓ Bước 3:
• Nếu p != NULL thì p trỏ tới phần tử cần tìm
• Ngược lại: không có phần tử cần tìm.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 43


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm trên danh sách

NODEPTR Search(NODEPTR phead, int x){


NODEPTR p=phead;
while(p!=NULL)
{
if(p->info==x)
break;
p=p->next;
}
return p;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 44


Khoa Hệ Thống Thông Tin Quản lý

Sắp xếp danh sách


➢Áp dụng các giải thuật sắp xếp đã học để tiến hành sắp xếp
danh sách.
void Sort(NODEPTR &phead){
NODEPTR p,q;
int tam;
for(p=phead;p->next!=NULL;p=p->next)
for (q=p->next;q!=NULL;q=q->next)
if(p->info>q->info)
{
tam=p->info;
p->info=q->info;
q->info=tam;
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 45


Khoa Hệ Thống Thông Tin Quản lý

Bài tập

• Dùng danh sách liên kết quản lý sinh viên trong lớp
(mssv, họ, tên, ngày sinh, điểm tổng kết học kỳ).
• Thực hiện các thao tác: thêm, bớt, sắp xếp sinh viên
(theo điểm tổng kết) trong danh sách

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 46


Khoa Hệ Thống Thông Tin Quản lý

TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HCM


KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

NGĂN XẾP
STACK

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 47


Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Giới thiệu về Stack


❖Hiện thực Stack
❖Một số bài toán ứng dụng Stack

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 48


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

Khái niệm về Stack


• Stack có thể được xem là một dạng danh sách đặc biệt
trong đó các tác vụ thêm vào hoặc xóa đi một phần tử
chỉ diễn ra ở một đầu gọi là đỉnh Stack. Trên Stack các
nút được thêm vào sau lại được lấy ra trước nên cấu
trúc Stack hoạt động theo cơ chế vào sau ra trước -
LIFO (Last In First Out).
• Hai thao tác chính trên Stack:
- Tác vụ push dùng để thêm một phần tử vào đỉnh
Stack
- Tác vụ pop dùng để xoá đi một phần tử ra khỏi đỉnh
Stack.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 49
Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

• Hình sau đây mô tả hình ảnh của Stack qua các tác vụ:
- push(s,A): hình a.
- push(s,B): hình b.
- pop(s): hình c.
- push(s,C): hình d.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 50


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

Pop
Push

Top

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 51


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

• Mô tả Stack
Mô tả dữ liệu:
Stack là một kiểu dữ liệu trừu tượng có nhiều nút cùng kiểu
dữ liệu trải dài từ đáy Stack đến đỉnh Stack.
Mô tả các tác vụ:
- Tác vụ Init
Chức năng: khởi động Stack
Dữ liệu nhập: không
Dữ liệu xuất: Stack top trở về đầu Stack.
- Tác vụ IsEmpty
Chức năng: kiểm tra Stack có rỗng hay không.
Dữ liệu nhập: không.
Dữ liệu xuất: TRUE|FALSE.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 52


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

• Mô tả Stack
- Tác vụ Push
Chức năng: thêm nút mới tại đỉnh Stack.
Dữ liệu nhập: nút mới
Dữ liệu xuất: không.
- Tác vụ Pop
Chức năng: xóa nút tại đỉnh Stack.
Dữ liệu nhập: không
Điều kiện: Stack không bị rỗng.
Dữ liệu xuất: nút bị xoá.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 53


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

• Ứng dụng của Stack


- Stack thường được dùng để giải quyết các vấn đề có cơ chế LIFO.
- Stack dùng trong trình biên dịch của các ngôn ngữ lập trình như:
+ Kiểm tra cú pháp của các câu lệnh trong ngôn ngữ lập trình.
+ Xử lý các biểu thức toán học: kiểm tra tính hợp lệ của các dấu
trong ngoặc một biểu thức, chuyển biếu thức từ dạng trung tố
(infix) sang dạng hậu tố (postfix), tính giá trị của biểu thứ dạng
hậu tố.
+ Xử lý việc gọi các chương trình con.
- Stack thường được sử dụng để chuyển một giải thuật đệ qui
thành giải thuật không đệ qui.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 54


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Stack

• Hiện thực Stack bằng danh sách kề


Khai báo cấu trúc Stack: là một mẩu tin có hai trường:
- Trường top: là một số nguyên chỉ đỉnh Stack.
- Trường nodes: là mảng một chiều, mỗi phần tử của mảng là
một nút của Stack.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 55


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Stack

• Hiện thực Stack bằng danh sách kề

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 56


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Stack

• Hiện thực Stack bằng danh sách kề

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 57


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Stack

Hiện thực stack bằng danh sách liên kết


• Khai báo cấu trúc Stack:

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 58


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Stack

Hiện thực stack bằng danh sách liên kết

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 59


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Stack

Hiện thực stack bằng danh sách liên kết

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 60


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Stack

Hiện thực stack bằng danh sách liên kết

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 61


Khoa Hệ Thống Thông Tin Quản lý

TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HCM


KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

HÀNG ĐỢI
QUEUE

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 62


Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Giới thiệu về Queue


❖Hiện thực Queue
❖Hàng đợi có ưu tiên

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 63


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

• Queue (hàng đợi) là một dạng danh sách đặt biệt, trong đó
chúng ta chỉ được phép thêm các phần tử vào cuối hàng
đợi và lấy ra các phần tử ở đầu hàng đợi. Vì phần tử thêm
vào trước được lấy ra trước nên cấu trúc hàng đợi còn được
gọi là cấu trúc FIFO (First In First Out).

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 64


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

• Hàng đợi là cấu trúc được sử dụng rộng rãi trong thực
tế: người ta dùng hàng đợi để giải quyết các vấn đề có
cấu trúc FIFO như xử lý các dịch vụ của ngân hàng, để
xử lý các tiến trình đang đợi phục vụ trong các hệ điều
hành nhiều người sử dụng, quản lý các yêu cầu in trên
máy print servers…

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 65


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

• Queue là 1 cấu trúc dữ liệu:


– Gồm nhiều phần tử có thứ tự
– Hoạt động theo cơ chế “Vào trước – Ra trước”
(FIFO – First In, First Out)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 66


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

Front

Append Take

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 67


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

• Khái niệm về Queue


Hàng đợi chứa các nút có cùng kiểu dữ liệu trải dài từ
đầu hàng đợi (front) đến cuối hàng đợi (rear). Hai tác
vụ chính trên hàng đợi:
- insert – thêm nút mới vào cuối hàng đợi
- remove – dùng để xoá một phần tử ra khỏi hàng đợi.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 68


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 69


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

• Mô tả Queue
Mô tả dữ liệu
Hàng đợi là một kiểu dữ liệu trừu tượng có nhiều nút cùng kiểu dữ
liệu trải dài từ đầu hàng đợi đến cuối hàng đợi.
Mô tả các tác vụ cơ bản:
- Tác vụ init
Chức năng: khởi động hàng đợi
Dữ liệu nhập: không
Dữ liệu xuất: hai con trỏ front và rear được gán các giá trị phù hợp.
- Tác vụ IsEmpty
Chức năng: kiểm tra hàng đợi có bị rỗng hay không
Dữ liệu nhập: không
Dữ liệu xuất: TRUE|FALSE

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 70


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

• Tác vụ insert
Chức năng: Thêm nút mới vào hàng đợi.
Dữ liệu nhập: nút mới
Điều kiện: hàng đợi không bị đầy.
Dữ liệu xuất: không.
• Tác vụ remove
Chức năng: lấy nút tại đầu hàng đợi
Dữ liệu nhập: không
Điều kiện: hàng đợi không bị rỗng
Dữ liệu xuất: thông tin nút bị lấy ra.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 71


Khoa Hệ Thống Thông Tin Quản lý

Giới thiệu về Queue

Ứng dụng của hàng đợi


• Hàng đợi được dùng để giải quyết các vấn đề có cơ
chế FIFO (First In First Out).
• Trong thực tế người ta thường cài đặt hàng đợi trong
các chương trình xử lý các dịch vụ ngân hàng, xử lý
các tác vụ đang đợi phục vụ trong các hệ điều hành
đa người sử dụng, quản lý các yêu cầu in trong máy
server printers…

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 72


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Queue

• 6.2.1 Dùng mảng vòng hiện thực hàng đợi


Đây là cách thường dùng nhất để cài đặt hàng đợi theo kiểu kế tiếp. Lúc
này ta xem mảng như là mảng vòng chứ không phải là mảng thẳng: nút
nodes[0] xem như là nút sau của nút nodes[MAXQUEUE -1]

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 73


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Queue

• 6.2.1 Dùng mảng vòng hiện thực hàng đợi

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 74


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Queue

• 6.2.1 Dùng mảng vòng hiện thực hàng đợi

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 75


Khoa Hệ Thống Thông Tin Quản lý

Hiện thực Queue

• 6.2.2 Dùng danh sách liên kết hiện thực hàng đợi
Ta có thể cài đặt hàng đợi như một danh sách liên kết: con
trỏ đầu danh sách liên kết front chỉ nút tại đầu hàng đợi, con
trỏ rear trỏ đến nút cuối cùng của hàng đợi.
Hình vẽ sau thể hiện cách cài đặt hàng đợi bằng danh sách
liên kết.

• Với cách cài đặt này ta có thể hiện thực các tác vụ của hàng
đợi như: Insert, Remove, IsEmpty…trên danh sách liên kết.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 76


Khoa Hệ Thống Thông Tin Quản lý

Hàng đợi có ưu tiên

• Hàng đợi hoạt động trên nguyên tắc nút nào vào trước được
lấy ra trước, nút nào vào sau được lấy ra sau là hàng đợi
không có ưu tiên.
• Trong thực tế có một dạng hàng đợi khác hoạt động theo cơ
chế: nút nào có độ ưu tiên cao hơn sẽ được lấy ra trước, nút
nào có độ ưu tiên thấp hơn thì lấy ra sau. Hàng
đợi lúc này gọi là hàng đợi có ưu tiên (priority queue).
• Có 2 loại hàng đợi có ưu tiên:
- Hàng đợi có ưu tiên tăng: nút có độ ưu tiên cao nhất được
lấy ra.
- Hàng đợi có ưu tiên giảm: nút có độ ưu tiên giảm sẽ được
lấy ra trước.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 77


Khoa Hệ Thống Thông Tin Quản lý

Tóm tắt

• Cấu trúc Queue là danh sách đặc biệt với thao tác thêm
vào được thực hiện ở cuối danh sách và lấy ra ở đầu
danh sách. Queue hoạt động theo cơ chế FIFO.
• Các thao tác cơ bản trên Queue: Init, isEmpty, Insert,
Remove
• Ứng dụng Queue trong bài toán hàng đợi “Vào trước ra
trước” FIFO: hệ thống print server, cơ chế thông điệp,
bộ đệm, hàng đợi xử lý sự kiện… Các ứng dụng đặt vé
tàu lửa, máy bay… Các hệ thống rút tiền.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 78


TRƯỜNG ĐẠI HỌC NGÂN HÀNG TPHCM
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 4
CÂY - TREE
1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Các khái niệm cơ bản


❖Cách biểu diễn cây
❖Cây nhị phân
❖Duyệt cây nhị phân
❖Cây nhị phân tìm kiếm

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm cây (trong máy tính)

Gốc

Nhánh
Nút

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 3


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm cây (trong máy tính)

• Cây là tập hữu hạn các nút (tree node), sao cho
– Có một nút gọi là nút gốc (root)
– Các nút còn lại được phân hoạch thành n tập
riêng biệt T1, T2 , ... , Tn, mỗi tập Ti là một cây
– Giữa các nút có quan hệ phân cấp (hierarchical
relationship) gọi là “quan hệ cha con”
• Cây không có nút gọi là cây rỗng (null tree)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm cây (trong máy tính)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 5


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm cây (trong máy tính)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm cây (trong máy tính)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 7


Khoa Hệ Thống Thông Tin Quản lý

Biễu diễn cây

• Bằng đồ thị
• Bằng giản đồ
• Bằng danh sách (các dấu ngoặc lồng nhau)
• Bằng phương pháp Indentatio

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Khoa Hệ Thống Thông Tin Quản lý

Biễu diễn cây

• Bằng đồ thị
A

B C D
A B

C D E
E F G H
F G H I

J I J K

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 9


Khoa Hệ Thống Thông Tin Quản lý

Biễu diễn cây

• Bằng giản đồ

D B

A
J
G H
I
E
C F

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Khoa Hệ Thống Thông Tin Quản lý

Biễu diễn cây

• Bằng danh sách (các dấu ngoặc lồng nhau)

(/( A (C (F), D (G ( J ) ) ) ), (B (E ( H, I ) ) ) ) A

/
B C D
A B

C D E E F G H I J
F G H I
K L M
J
( A ( B ( E ( K, L ), F ), C ( G ), D ( H ( M ), I, J ) ) )

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 11


Khoa Hệ Thống Thông Tin Quản lý

Biễu diễn cây

• Bằng phương pháp Indentatio


A
C
F /
D
A B
G
J C D E
B
F G H I
E
H J
I

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 12


Khoa Hệ Thống Thông Tin Quản lý

Các thuật ngữ

• Bậc của nút và bậc của cây A


– Nút A: bậc 3, nút C bậc 1
– Bậc của cây: 3 B C D
• Nút gốc, Nút lá và nút nhánh
E F G H I J
• Nút cha (Parent), nút con
(children) K L M

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 13


Khoa Hệ Thống Thông Tin Quản lý

Các thuật ngữ

• Đường đi (path)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 14


Khoa Hệ Thống Thông Tin Quản lý

Các thuật ngữ

• Mức của nút và chiều cao của cây


Root
1

Chiều cao
2
(độ sâu) của
cây: 5
3

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 15


Khoa Hệ Thống Thông Tin Quản lý

Các thuật ngữ

• Tổ tiên (ancestors) của một nút


– Tổ tiên của nút J /
• Con cháu (Descendant) của một A B
nút:
– Con cháu của B C D E
• Các con của cùng một cha gọi là F G H I
anh em ruột (siblings)
J

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 16


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân – Binary Tree


• Định nghĩa: Cây nhị phân là một cấu trúc gồm một tập
hữu hạn các nút cùng kiểu dữ liệu (tập nút này có thể
rỗng) và được phân thành 3 tập con:
- Tập con thứ nhất có một nút gọi là nút gốc (root).
- Hai tập con còn lại tự thân hình thành hai cây nhị phân là
nhánh cây con bên trái (left subtree) và nhánh cây con
bên phải (right subtree) của nút gốc. Nhánh cây con bên
trái hoặc bên phải cũng có thể là cây rỗng.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 17


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân

• Cây nhị phân biểu diễn biểu thức toán học

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 18


Khoa Hệ Thống Thông Tin Quản lý

Tính chất của cây nhị phân


• Số nút tối đa mức i trong cây 2i-1
• Số nút tối đa trong cây là 2h-1 (h chiều cao của cây)
 Chiều cao của cây h 
log2N (N là số nút trong cây).

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 19


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân hoàn chỉnh

A B

C D I E

G J G

Cây nhị phân có chiều cao là h thì có đầy đủ các nút


từ mức 1 đến mức h-1 (hay nói cách khác: Mọi nút
có mức <h-1 đều có đúng 2 nút con). Các nút ở mức
h sẽ được lấp từ trái sang phải

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 20


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân đầy đủ

A B

C D I E

Các nút đạt tối đa ở cả mọi mức (Cây


nhị phân có chiều cao là h thì tất
cả các nút nằm ở mức từ 1 đến
mức (h-1) đều có 2 nút con)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 21


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân gần đầy

A B

C D E
I

J G G

Các nút ứng với các mức (trừ mức cuối) đều đạt tối đa,
ở mức cuối, các nút không đạt đều về phía trái

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 22


Khoa Hệ Thống Thông Tin Quản lý

Tổ chức lưu trữ cây nhị phân

• Sử dụng mảng một chiều (lưu trữ kế tiếp)


– Đánh số thứ tự từ gốc, tại mỗi mức, đánh số các nút từ trái
sang phải, từ mức thấp đến mức cao
• Sử dụng con trỏ (Lưu trữ liên kết)
– Quản lý cây thông qua nút gốc (root)
– Mỗi nút cấp phát động, bao gồm dữ liệu và hai con trỏ pleft,
pright, liên kết tới cây con trái và cây con phải
– Nút lá có hai liên kết trái phải đều rỗng

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 23


Khoa Hệ Thống Thông Tin Quản lý

Cấu trúc của nút

typedef struct nodetype{


int data;
struct nodetype *pleft;
struct nodetype *pright;
}Node;

typedef Node * NODEPTR;


Data

pLeft Data pRight


pLeft pRight

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 24


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

• Định nghĩa
– Là phép xử lý các nút trên cây, mỗi nút một lần
• Duyệt cây theo thứ tự trước (Preorder)
• Duyệt cây theo thứ tự giữa (Inorder)
• Duyệt cây theo thứ tự sau (Postorder)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 25


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

• Duyệt cây theo thứ tự trước (NLR)


– Thăm gốc
– Duyệt cây con trái theo thứ tự trước
– Duyệt cây con phải theo thứ tự trước

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 26


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

• Duyệt cây theo thứ tự trước (NLR)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 27


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

void preorder(NODEPTR root)


{
if (root!=NULL) {
cout << root->data <<“ “;
preorder(root->pLeft);
predorder(root->pRight);
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 28


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

• Duyệt cây theo thứ tự giữa (LNR)


– Duyệt cây con trái theo thứ tự giữa
– Thăm gốc
– Duyệt cây con phải theo thứ tự giữa

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 29


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

• Duyệt cây theo thứ tự giữa (LNR)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 30


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

void inorder(NODEPTR root)


{
if (root) {
inorder(root->pLeft);
cout << root->data<<“ “;
indorder(root->pRight);
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 31


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

• Duyệt cây theo thứ tự sau (LRN)


– Duyệt cây con trái theo thứ tự sau
– Duyệt cây con phải theo thứ tự sau
– Thăm gốc

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 32


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 33


Khoa Hệ Thống Thông Tin Quản lý

Duyệt cây nhị phân

void postorder(NODEPTR root)


{
if (root) {
postorder(root->left);
postdorder(root->right);
count <<root->data<<“ “;
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 34


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân tìm kiếm - Binary Search Tree – BST

• Định nghĩa:
44

18 88

13 37 59 108

15 23 40 55 71

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 35


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân tìm kiếm - Binary Search Tree – BST

typedef struct nodetype{


int data;
struct nodetype *pleft;
struct nodetype *pright;
}Node;
typedef Node * NODEPTR;

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 36


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân tìm kiếm - Binary Search Tree – BST

• Tạo nút
NODEPTR CreateNode (int x){
NODEPTR p = new NODE;
p->data=x;
p -> pleft=NULL;
p ->pright=NULL;
return p;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 37


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân tìm kiếm - Binary Search Tree – BST

• Kiểm tra cây có rỗng không


int IsEmpty(NODEPTR p)
{
return (p==NULL);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 38


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân tìm kiếm - Binary Search Tree – BST

• Các thao tác trên cây BST


– Thêm vào phần tử có khóa x
– Tìm nút có khóa x
– Xóa một nút có khóa là x
– Tìm nút có khóa nhỏ nhất
– Tìm nút có khóa lớn nhất
– Giải phóng cây

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 39


Khoa Hệ Thống Thông Tin Quản lý

Cây nhị phân tìm kiếm - Binary Search Tree – BST

• int Insert( int X, NODEPTR &root);


• int Delete( int X, NODEPTR &root);
• NODEPTR Find( int X, NODEPTR root);
• NODEPTR FindMin(NODEPTR root);
• NODEPTR FindMax(NODEPTR root);
• void MakeEmpty(NODEPTR &root);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 40


Khoa Hệ Thống Thông Tin Quản lý

Thêm 1 phần tử vào Cây nhị phân tìm kiếm

• Thêm vào phần tử có khóa x root


44 X > 44
Them X= 50

18 X < 88 88

13 37 59 108
X < 59

15 23 40 55 71

X < 55
50

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 41


Khoa Hệ Thống Thông Tin Quản lý

Thêm 1 phần tử vào Cây nhị phân tìm kiếm


int InsertNode(NODEPTR &root, int x)
{
if(root!=NULL)
{
if(root->data==x) //neu da co x trong cay
return -1;
if (root->data>x)
return InsertNode(root->pleft,x);
else
return InsertNode(root->pright,x) ;
}
root=CreateNode(x) ;
if (root==NULL)
return 0;
root->data=x;
root->pleft=root->pright=NULL;
return 1;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 42


Khoa Hệ Thống Thông Tin Quản lý

Tìm 1 nút có khóa X

• Tìm nút có khóa X root


44 X >44
Tìm X=55

18 88
X < 88

13 37 59 108
X < 59

15 23 40 55 71

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 43


Khoa Hệ Thống Thông Tin Quản lý

Tìm 1 nút có khóa X

NODEPTR Search(NODEPTR root, int x)


{
if (root==NULL) return NULL;
if(root->data<x)
Search(root->pright,x);
else
if(root->data>x)
Search(root->pleft,x);
else
return root;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 44


Khoa Hệ Thống Thông Tin Quản lý

Tìm 1 nút có khóa X

• Tìm nút có khóa X, không dùng đệ qui


NODEPTR Search2(int X, NODEPTR root)
{
NODEPTR p = root;
while (p != NULL)
{
if(X == p->Data) return p;
else
if(x < p->Data) p = p->pLeft;
else
p = p->pRight;
}
return NULL;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 45


Khoa Hệ Thống Thông Tin Quản lý

Tìm 1 nút có khóa nhỏ nhất

NODEPTR FindMin(NODEPTR root)


{ if ( root == NULL )
return NULL;
else if( root->pLeft == NULL )
return root;
else
return FindMin( root->pLeft );
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 46


Khoa Hệ Thống Thông Tin Quản lý

Tìm 1 nút có khóa lớn nhất

NODEPTR FindMax(NODEPTR root)


{
if (root != NULL )
while (root->pRight != NULL )
root = root->pRight;
return root;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 47


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút có khóa X

• Xóa một nút có khóa X trên cây BST, có 3


trường hợp
– Nút có khóa X là nút lá
– Nút có khóa X chỉ có một nút con (trái hoặc
phải)
– Nút có khóa X có đủ cả hai con

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 48


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút có khóa X

• Trường hợp 1: nút có khóa X trên cây là nút lá

root
44
Xóa: X=40

18 88
Đơn giản : Xóa
nút X, vì nó
không móc nối
13 37 59 108
đến nút nào khác

15 23 40 55 71

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 49


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút có khóa X

• Trường hợp 2: nút có khóa X trên cây có


một nút con (trái hoặc phải)

44 root root
Xóa X=37 44
Xóa X=37

18 88
18 88

13 37 59 108 13 37 59 108

15 23 55 71 15 40 55 71

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 50


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút có khóa X

• Trường hợp 3 : Nút X có một cây hai con trái và phải


– Hủy gián tiếp

Xóa nút X=18 44 root

18 88

15
13 37 59 108

15 23 40 55 71

30

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 51


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút có khóa X

int Delete(NODEPTR &root, int X)


{ NODEPTR p;
if ( root == NULL )
return 0 ; // cây rỗng, không tìm thấy
else
if ( X < root ->data) // xóa trên cây con trái
return Delete(root->pleft,X);
else
if ( X > root->data ) // xóa trên cây con phải
return Delete(root->pright,X);
else // tìm ra nút cần xoa

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 52


Khoa Hệ Thống Thông Tin Quản lý

Xóa 1 nút có khóa X


if ( root->pleft && root->pright ) // Có hai con
{ p = FindMax(root->pleft); //tìm nút có khóa lớn
nhất trên con trái
root->data = p ->data;
return Delete(root->pleft,root->data);
}
else // có 1 con hoac không có con
{ p = root;
if ( root-> pleft == NULL ) // xử lý như không có con
root = root->pright;
else if ( root->pright == NULL )
root = root->pleft;
delete p;
}
return 1;
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 53


Khoa Hệ Thống Thông Tin Quản lý

Giải phóng cây BST

void MakeEmpty(NODEPTR &root);


{
if (root)
{
MakeEmpty(root->pLeft);
MakeEmpty(root->pRight);
delete root ;
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 54


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Định nghĩa
– Cây m phân là cây mà mỗi nút có tối đa m nút
con (cây con)
– Biểu diễn cây m phân bằng liên kết động
• Mỗi nút có m+1 trường, với m mối nối
• Với cây m phân đầy đủ, có n(m-1)+1 mối liên kết
NULL

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 55


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Biểu diễn cây tổng quát


– Biểu diễn cây tổng quát bằng cây nhị phân
– Đối với một nút trên cây tổng quát
• Một nút con nằm ở vị trí trái nhất (con cả 1)
• Một nút kế cận với nút đang xét kể từ trái sang (em
kế - 2)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 56


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Biểu diễn cây tổng quát


Data
R R FirstChild NextSibling

A D B A

C H I J G E C D

H I B
typedef struct TreeNode * PtrToNode;
struct TreeNode
{int info; J G
PtrToNode FirstChild; // con caả
PtrToNode NextSibling; //em kê E
};

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 57


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Phép duyệt cây tổng quát NLR(T)


– Nếu T rỗng, dừng
– Ngược lại, T1,…,Tn là cây con gốc T
• Thăm gốc của T
• NLR(T1), T1 cây con thứ nhất của gốc T
• Duyệt cây con T2,…,Tn của T theo thứ tự trước

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 58


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Phép duyệt cây tổng quát LNR(T)


– Nếu T rỗng, dừng
– Ngược lại, T1,…,Tn là cây con gốc T
• LNR(T1), T1 cây con thứ nhất của gốc T
• Thăm gốc của T
• Duyệt cây con T2,…,Tn của T theo thứ tự giữa

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 59


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Phép duyệt cây tổng quát LRN(T)


– Nếu T rỗng, dừng
– Ngược lại, T1,…,Tn là cây con gốc T
• LNR(T1), T1 cây con thứ nhất của gốc T
• Duyệt cây con T2,…,Tn của T theo thứ tự giữa
• Thăm gốc của T

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 60


Khoa Hệ Thống Thông Tin Quản lý

Cây tổng quát

• Duyệt cây theo mức


– Duyệt cây theo chiều rộng
– Ý tưởng
• Tổ chức thành một hàng đợi
• Đưa nút gốc vào hàng đợi
• Lặp
– Lấy một nút ra khỏi hàng đợi
– Duyệt nút T
– Đưa các nút con của T (nếu có) vào hàng đợi

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 61


Khoa Hệ Thống Thông Tin Quản lý

Tóm tắt

Trong bài này, học viên cần nắm:


• Cây nhị phân là một cấu trúc gồm một tập hữu hạn các nút
cùng kiểu dữ liệu tổ chức theo cấu trúc phân cấp.
• Các thao tác cơ bản trên cây: Init, IsEmpty, InsertLeft,
InsertRight, DeleteLeft, DeleteRight, PreOder, InOder,
PostOder, Search, ClearTree.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 62


Khoa Hệ Thống Thông Tin Quản lý

Tóm tắt

BST là cây nhị phân mà mỗi nút thoả: Giá trị của tất cả nút con
trái < giá trị của nút đó. Giá trị của tất cả nút con phải > giá trị
của nút đó.
• Cây nhị phân tìm kiếm là một dạng đặc biệt của cây nhị
phân nên vẫn dùng các tác vụ trong phần trên hiện thực cho
cây nhị phân tìm kiếm, chỉ khác ở các tác vụ: tìm kiếm, thêm
vào cây một phần tử và xoá một phần tử ra khỏi cây nhị
phân tìm kiếm.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 63


Khoa Hệ Thống Thông Tin Quản lý

Câu hỏi ôn tập

Câu 1: Xét tác vụ insert và remove để thêm nút và xoá


nút trên cây nhị phân tìm kiếm.
a) Vẽ lại hình ảnh của cây BST nếu thêm các nút vào
cây theo thứ tự như sau:
8, 3, 5, 2, 20, 11, 30, 9, 18, 4.
b) Vẽ lại hình ảnh của cây trên nếu ta lần lược xoá 2
nút 5 và 20.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 64


Khoa Hệ Thống Thông Tin Quản lý

Câu hỏi ôn tập

Câu 2: Cài đặt cấu trúc dữ liệu liên kết cho cây nhị phân tìm
kiếm, với các thao tác:
1. Nhập các nút trong cây
2. Duyệt cây theo 3 phương pháp
3. Đếm số nút lá/số nút lẻ/chẳn trong cây
4. Số nút có 1 con, số nút có 2 con
5. Đếm số nút ở mức lẻ/chẳn (mức lẻ: mức 1,3,5,7…; mức chẵn: mức 2,4,6…)
6. Đếm tổng số nút trong cây
7. Đếm tổng giá trị nút chẵn/lẻ trong cây
8. Tính chiều cao của cây
9. Tìm 1 nút có khóa x trong cây
10. Tìm nút có khóa lớn nhất/nhỏ nhất
11. Thêm 1 nút có khóa x vào cây
12. Xóa 1 nút có khóa x khỏi cây
13. Xóa toàn bộ cây
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 65
TRƯỜNG ĐẠI HỌC NGÂN HÀNG TPHCM
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 5
ĐỒ THỊ - GRAPH
1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Định nghĩa và các khái niệm


❖Biểu diễn đồ thị
❖Duyệt đồ thị

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

Vinh Đà Nẵng Cần Thơ

Hà Nội TP. Hồ Chí Minh

Hải Phòng Huế Nha Trang

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

• Đồ thị G = (V,E)
– V = tập hợp hữu hạn các phần tử (đỉnh hay nút)
– E  V × V, tập hữu hạn các cạnh (cung)

a b Đỉnh

c Cung

d e

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

• BIỂU DIỄN MẠCH ĐIỆN

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

• YÊU CẦU TRÌNH TỰ

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

• TRUYỀN THÔNG MẠNG MÁY TÍNH

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

• LUỒNG GIAO THÔNG

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Định nghĩa

• SƠ ĐỒ ĐƯỜNG PHỐ

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm

• Cho đồ thị G = (V, E). V gọi là tập các đỉnh (vertex )


và E gọi là tập các cạnh (Edges)
G được gọi là đơn đồ thị nếu giữa hai đỉnh u, v của
V có nhiều nhất là 1 cạnh trong E nối từ u tới v

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm

• G được gọi là đa đồ thị nếu giữa hai đỉnh x, y của V


có thể có nhiều hơn 1 cạnh trong E nối từ x tới y

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm

• Nếu (x,y)  E
• x gọi là đỉnh gốc, y là ngọn
• Nếu x ≡ y, (x,y) gọi là khuyên
• Đường đi: Một dãy u1,u2,…,un, ui  V (i=1,n) gọi
là một đường, nếu (ui-1,ui)  E

(1, 2, 3, 4) là đường đi đơn độ dài bằng 3, đi từ đỉnh 1 tới đỉnh 4. Bởi (1, 2) (2, 3) và (3,
4) đều là các cạnh (hay cung)
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn
Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm

• Độ dài đường: length(u1,u2,…,un)=n


• Đường đi đơn: (u1,u2,…,un) là đường đi đơn, nếu
ui≠uj, 1<i≠j<n (là đường đi, mà các đỉnh phân
biệt, ngoại trừ đỉnh đầu và đỉnh cuối)
B

A C

Đường đi đơn
D

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

• Đồ thị có hướng (directed graph): G được gọi là đồ thị


có hướng nếu các cạnh trong E là có định hướng, có thể
có cạnh nối từ đỉnh x tới đỉnh y nhưng chưa chắc đã có
cạnh nối từ đỉnh y tới đỉnh x. Cách khác:
– (x,y)  E : (x,y) ≠ (y,x)
• Đồ thị vô hướng: G được gọi là đồ thị vô hướng nếu các
cạnh trong E là không định hướng, tức là cạnh nối hai
đỉnh x, y bất kỳ cũng là cạnh nối hai đỉnh y, x. Cách khác:
– (x,y)  E : (y,x)  E
– (x,y) ≡ (y,x)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

Đồ thị vô hướng Đồ thị có hướng

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

• Chu trình (cycle) : Là đường đi khép kín, tức là có


đỉnh đầu trùng với đỉnh cuối:
– (cycle) = (u1,u2,…,un), u1≡ un

A C

D Chu trình
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn
Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

Bậc của đỉnh


Giả sử G là đồ thị vô hướng, vV là một đỉnh nào đó
• Bậc của đỉnh v, deg(v), là số cạnh kề với nó.
• Đỉnh bậc 0 được gọi là đỉnh cô lập (isolated).
• Đỉnh bậc 1 được gọi là đỉnh treo (pendant).

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

• Tính liên thông (connectivity)


– Trong đồ thị G, hai đỉnh x, y gọi là liên thông
(connected), nếu có một đường từ x đến y
– Đồ thị vô hướng được gọi là liên thông nếu luôn
tìm được đường đi giữa hai đỉnh bất kỳ của nó.
➔ G liên thông, nếu x, y  V,  đường đi từ x
đến y

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

Đồ thị liên thông Đồ thị không liên thông

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Các khái niệm (tt)

• Đồ thị có trọng số: Đồ thị G gọi là có trọng


số, nếu mỗi cung được gán một giá trị số đặc
trưng

0
10
20

1 1
2
4
5
3

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn đồ thị

• Biểu diễn bằng ma trận kề


– Adjacency matrice
• Biểu diễn bằng danh sách kề
– Adjacency list

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề

• Xét G=(V,E) với V={x1,…,xn}


• Biểu diễn G bằng ma trận A=(aij), i,j=1..n
– aij=1, nếu Ǝ (xi,xj)  E
– aij=0, nếu !Ǝ (xi,xj)  E

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề (tt)

A[i][j] 0 1 2 3
0 0 0 1 1 0
1 1 0 1 1
1 2 1 1 0 1
2
3 0 1 1 0
3 0 1 1 0
1 0 1 1
A= 1 1 0 1
0 1 1 0

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề (tt)

A[i][j] 0 1 2 3
0 0 1 1 1
0 1 0 0 0 1
2 0 0 0 1
1
2 3 0 0 0 0

3 0 1 1 1
0 0 0 1
A=
0 0 0 1
0 0 0 0

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề (tt)

x2 0 1 1 0 0
x1 x3 0 0 0 0 1
0 1 0 0 0
0 0 1 0 0
x5 x4 1 0 0 1 0

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề (tt)

x2 0 1 1 0 0
x1 x3 0 0 0 1 1
0 1 0 0 0
0 1 1 0 0
x5 x4 1 0 0 1 1

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề (tt)

A[i][j] 0 1 2 3
0 0 20 10 1
1 20 0 0 5
0
20 2 10 0 0 4
10
3 1 5 4 0
1 1
2
5 0 20 10 1
4 20 0 0 5
3 A=
10 0 0 4
1 5 4 0

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng ma trận kề (tt)

• Chú ý
– Đối với đồ thị không định hướng, ma trận kề là
ma trận đối xứng
– Đối với đồ thị định hướng, số lượng phần tử 0
khá lớn
– Đối với đồ thị có trọng số, thay thế giá trị 1
bằng giá trị trọng số

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng danh sách kề

• Là một mảng các danh sách


• Ở đây, n hàng của ma trận kề thay thế bằng
n danh sách liên kết động
• Mỗi đỉnh của G có một danh sách, mỗi nút
trong danh sách thể hiện các đỉnh lân cận
của nút này
– Cấu trúc mỗi nút
• id: tên đỉnh (chỉ số, danh hiệu)
• next: con trỏ đến nút kế tiếp

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng danh sách kề (tt)

0 1 2 3
0 1 3

1 2 3
2
3
3

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng danh sách kề (tt)

x2 x[1] 2 3
x1 x3 x[2] 5
x[3] 2
x[4] 3
x5 x4
x[5] 1 4

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng danh sách kề (tt)

0 1 10 2 20 3 1
0
10
20 1 0 10 3 4
1 1
2 2 0 20 3 5
4
5 3 0 1 1 4 2 5
3

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Biểu diễn bằng danh sách kề (tt)

• Chú ý
– Các nút đầu danh sách được lưu vào một mảng
(truy cập nhanh)
– Với đồ thị không định hướng có n đỉnh và e
cạnh, thì cần n nút đầu và 2e nút ‘trong’ danh
sách
– Với đồ thị định hướng có n đỉnh và e cạnh, thì
chỉ cần e nút ‘trong’ danh sách
– Thứ tự các nút không quan trọng

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép duyệt đồ thị

• Từ một đỉnh, liệt kê tất cả các đỉnh của


đồ thị
– Phép tìm kiếm theo chiều sâu
• Depth First Search - DFS
– Phép tìm kiếm theo chiều rộng
• Breadth First Search - BFS

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều sâu

• Ý tưởng
– Tư tưởng cơ bản của thuật toán tìm kiếm
theo chiều sâu là bắt đầu tại một đỉnh v0
nào đó, chọn một đỉnh u bất kỳ kề với v0 và
lấy nó làm đỉnh duyệt tiếp theo.
– Cách duyệt tiếp theo được thực hiện tương
tự như đối với đỉnh v0 với đỉnh bắt đầu là u

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều sâu (tt)

x2

x1 x3

x34

x5 x4 x1523
x21

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều sâu (tt)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều sâu (tt)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều sâu (tt)

• Nhận xét
– Thời gian thực hiện giải thuật ~ (n+e), nếu G
được biểu diễn bằng danh sách kề
– Thời gian thực hiện giải thuật ~ n2, nếu G
được biểu diễn bằng ma trận kề
– Giải thuật này sử dụng để chứng minh một đồ
thị có liên thông hay không
– Với thuật toán tìm kiếm theo chiều sâu, đỉnh
thăm càng muộn sẽ trở thành đỉnh sớm được
duyệt xong. Đó là kết quả tất yếu vì các đỉnh
thăm được nạp vào stack trong thủ tục đệ quy.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều rộng

• Tại điểm v bất kỳ, duyệt đỉnh v, thu được tập hợp
W gồm các đỉnh w xuất phát từ v
• Lặp lại thao tác trên đối với tất cả các đỉnh w
trong W, thu được tập hợp đỉnh Z
• Lặp lại thao tác trên đối với tất cả các đỉnh z
trong Z
• Lặp lại cho đến khi tất cả mọi đỉnh đều được
duyệt qua ít nhất một lần

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều rộng (tt)

x2 x1 x2 x3 x5 x2 x1 x4

x1 x3

x5 x4

Tham khảo

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều rộng (tt)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Phép tìm kiếm theo chiều rộng (tt)

• Nhận xét
– Thời gian thực hiện giải thuật ~ (n+e), nếu
G được biểu diễn bằng danh sách kề
– Thời gian thực hiện giải thuật ~ n2, nếu G
được biểu diễn bằng ma trận kề

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Cây khung (Spanning tree)

• T=(V,E’)  G=(V,E), với E  E’ bao gồm


các cung thuộc một phép duyệt từ một
đỉnh đến các đỉnh còn lại trong V
• Giá của cây khung T = tổng trọng số của
các cung thuộc E’

Cây khung T
Đồ thị G của đồ thị G

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Cây khung (Spanning tree)

• Chú ý
– Một đồ thị G có thể có nhiều cây khung
– Cây khung theo chiều rộng, theo chiều sâu
– Các cung trong cây khung không tạo nên chu
trình
• Giữa hai đỉnh trong một cây khung chỉ tồn tại duy
nhất một đường đi từ đỉnh này đến đỉnh kia
– Nếu đồ thị có n đỉnh, thì cây khung có n-1 cạnh

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Cây khung cực tiểu

• Là cây khung với tổng các trọng số là


cực tiểu

6 10 6 10

1 1
7
20

5 5

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


Khoa Hệ Thống Thông Tin Quản lý

Q&A

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn


TRƯỜNG ĐẠI HỌC NGÂN HÀNG TPHCM
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 6
CÁC GIẢI THUẬT SẮP XẾP
1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Tại sao phải sắp xếp dữ liệu?


❖Phương pháp nổi bọt (Bubble Sort)
❖Phương pháp chọn (Selection Sort)
❖Phương pháp chèn (Insertion Sort)
❖Phương pháp đổi chỗ (Interchange Sort)
❖Phương pháp sắp xếp nhanh (Quick Sort)
Đọc thêm:
❖ Phương pháp sắp vun đống (Heap Sort)
❖ Phương pháp sắp xếp trộn (Merge Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Tại sao phải sắp xếp dữ liệu?

Hãy tìm cuốn sách Cấu trúc dữ liệu và Giải Thuật?

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 3


Khoa Hệ Thống Thông Tin Quản lý

Tại sao phải sắp xếp dữ liệu?

Sắp xếp dữ liệu là gì?

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Khoa Hệ Thống Thông Tin Quản lý

Tại sao phải sắp xếp dữ liệu?

Sắp xếp là quá trình xử lý một danh sách các phần tử


(hoặc các mẫu tin) để đặt chúng theo một thứ tự thỏa
mãn một số tiêu chuẩn nào đó dựa trên nội dung
thông tin lưu giữ tại mỗi phần tử
Ví dụ:
- Hãy sắp xếp mảng số nguyên tăng dần
- Hãy sắp xếp Sinh viên theo tuổi tăng dần
- Hãy sắp xếp Sinh viên theo tuổi tăng dần, nếu tuổi
bằng nhau thì sắp xếp theo mã giảm dần.
- Hãy sắp xếp Sản phẩm theo đơn giá giảm dần, nếu
đơn giá bằng nhau thì sắp xếp theo ngày nhập
tăng dần.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 5
Khoa Hệ Thống Thông Tin Quản lý

Tại sao phải sắp xếp dữ liệu?

❖ Khái niệm nghịch thế:


 Xét một danh sách các số M0, M1, … Mn-1
 Nếu có i<j và Mi > Mj, thì ta gọi đó là một nghịch thế.
 Danh sách chưa sắp xếp sẽ có nghịch thế.
 Danh sách đã có thứ tự sẽ không chứa nghịch thế.
M0 ≤ M1 ≤ … ≤ Mn-1

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

➢ Ý tưởng chính:
 Xuất phát từ cuối (đầu) dãy, đổi chỗ các cặp phần
tử kế cận để đưa phần tử nhỏ (lớn) hơn trong cặp
phần tử đó về vị trí đúng đầu (cuối) dãy hiện hành,
sau đó sẽ không xét đến nó ở bước tiếp theo,
 Ở lần xử lý thứ i có vị trí đầu dãy là i

 Lặp lại xử lý trên cho đến khi không còn cặp phần
tử nào để xét.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 7


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp nổi bọt


(Bubble Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 9


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

 Bước 1 : i = 0; // lần xử lý đầu tiên


 Bước 2 : j = N-1; //Duyệt từ cuối dãy ngược về vị trí i
 Trong khi (j > i) thực hiện:
 Nếu M[j]<M[j-1]: M[j]↔M[j-1 ];//xét cặp phần tử kế cận
 j = j-1;
 Bước 3 : i = i+1; // lần xử lý kế tiếp
 Nếu i >=N-1: Hết dãy. Dừng
 Ngược lại : Lặp lại Bước 2.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

Ví dụ: sắp xếp dãy số sau


3,5,1,6,12,7,4,10,2

3
5
1
6
12
7
4
10
2
Nguồn minh họa: Thầy Trương Hoài Phan
0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 11
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
6
12
7
4
10
2

j=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 12
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
6
12
7
4
2
10

j=7

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 13
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
6
12
7
2
4
j=6 10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 14
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
6
12
2
7
4
j=5
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 15
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
6
2
12
2
7
j=5
j=4
4
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 16
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
2
6

j=3 12
2
7
4
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 17
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
5
i=0 1
2
6
j=2
12
2
7
4
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 18
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

3
1
i=0 5
2
j=1
6
12
2
7
4
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 19
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
5
2
i=1
6
12
2
7
4
10

J=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 20
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
5
2
i=1
6
12
2
7
4
10

j=7

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 21
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
5
2
i=1
6
12
2
4
7
j=6 10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 22
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
5
2
i=1
6
4
12
7
j=5
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 23
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
5
2
i=1
4
6
12
j=4
7
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 24
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
5
2
i=1
4

j=3 6
12
7
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 25
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
3
2
5
i=1
4
j=2
6
12
7
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 26
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
5
4
i=2
6
12
7
10

j=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 27
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
5
4
i=2
6
12
7
10

j=7

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 28
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
5
4
i=2
6
7
12
J=6 10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 29
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
5
4
i=2
6
7
12
J=5
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 30
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
5
4
i=2
6
7
j=4
12
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 31
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
i=2
J=3 6
7
12
10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 32
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
i=2
6
7
12
10

j=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 33
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5

i=3 6
7
J=4
10
J=5
J=6 12

J=7

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 34
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
6
7
i=4
10
J=5
J=6 12

J=7
J=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 35
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
6
7
10
i=5
J=6 12

J=7
J=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 36
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
6
7
10
i=6 12

J=7
J=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 37
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
6
7
10
12

i=7
J=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 38
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

1
2
3
4
5
6
7
10
12

i=8

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 39
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort) Cài đặt giải thuật
void BubbleSort(int M[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--)
{
if (M[j] < M[j - 1])// nếu có nghịch thế
{
int temp = M[j];
M[j] = M[j - 1];
M[j - 1] = temp;
}
}
}
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 40
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


Hãy giải thích từng bước quá trình chạy Bubble Sort
cho danh sách dưới đây:
int[] M = {100,3,60,35,2};
BubbleSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 41


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


int[] M = {100,3,60,35,2};
void BubbleSort(int M[], int n) BubbleSort(M);
{
int i, j; for 1:
for (i = 0; i < n - 1; i++)
{ (for1- lần 1)Khởi tạo i=0, kiểm tra i<n-1
for (j = n - 1; j > i; j--) i<5-10<4➔đúng
{
if (M[j] < M[j - 1])// nếu for 2:
có nghịch thế (for2- lần 1)Khởi tạo j=n-1=4, kiểm tra
{ j>i 4>0➔đúng
int temp = M[j];
M[j] = M[j - 1]; If: M[j] <M[j-1]M[4]<M[3]
M[j - 1] = temp;
} 2<35➔đúng, hoán đổi vị
} trí của hai phần tử này, ta có:
}
} M = {100,3,60,2,35};
(for2- lần 2) j--➔j=4-1=3,
kiểm tra j>i 3>0➔đúng
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 42
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


If: M[j] <M[j-1]M[3]<M[2]
void BubbleSort(int M[], int n)
2<60➔đúng, hoán đổi vị trí
{ của hai phần tử này, ta có:
int i, j; M = {100,3,2,60,35};
for (i = 0; i < n - 1; i++)
{
(for2- lần 3) j--➔j=3-1=2,
for (j = n - 1; j > i; j--) kiểm tra j>i 2>0➔đúng
{ If: M[j] <M[j-1]M[2]<M[1]
if (M[j] < M[j - 1])// nếu
có nghịch thế
2<3➔đúng, hoán đổi vị trí
{ của hai phần tử này, ta có:
int temp = M[j]; M = {100,2,3,60,35};
M[j] = M[j - 1];
M[j - 1] = temp; (for2- lần 4) j--➔j=2-1=1,
} kiểm tra j>i 1>0➔đúng
} If: M[j] <M[j-1]M[1]<M[0]
}
}
2<100➔đúng, hoán đổi vị trí
của hai phần tử này, ta có:
M = {2,100,3,60,35};
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 43
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


(for2- lần 5) j--➔j=1-1=0,
void BubbleSort(int M[], int n) kiểm tra j>i 0>0➔sai➔ngừng for 2
{ for 1:
int i, j; (for1- lần 2)i++➔i=0+1=1, kiểm tra i<n-1
for (i = 0; i < n - 1; i++)
{ i<5-11<4➔đúng
for (j = n - 1; j > i; j--) for 2:
{
(for2- lần 1)Khởi tạo j=n-1=4, kiểm tra
if (M[j] < M[j - 1])// nếu
có nghịch thế j>i 4>1➔đúng
{
int temp = M[j];
If: M[j] <M[j-1]M[4]<M[3]
M[j] = M[j - 1]; 35<60➔đúng, hoán đổi vị
}
M[j - 1] = temp;
trí của hai phần tử này, ta có:
}
}
M = {2,100,3,35,60};
} (for2- lần 2) j--➔j=4-1=3,
kiểm tra j>i 3>1➔đúng

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 44


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


If: M[j] <M[j-1]M[3]<M[2]
void BubbleSort(int M[], int n) 35<3➔sai➔không đổi vị trí,
{ danh sách vẫn là:
int i, j;
for (i = 0; i < n - 1; i++)
M = {2,100,3,35,60};
{ (for2- lần 3) j--➔j=3-1=2,
for (j = n - 1; j > i; j--) kiểm tra j>i 2>1➔đúng
{
if (M[j] < M[j - 1])// nếu
If: M[j] <M[j-1]M[2]<M[1]
có nghịch thế 3<100➔đúng, hoán đổi vị
{ trí của hai phần tử này, ta có:
int temp = M[j];
M[j] = M[j - 1]; M = {2,3,100,35,60};
M[j - 1] = temp;
} (for2- lần 4) j--➔j=2-1=1,
} kiểm tra j>i 1>1➔sai➔ngừng for 2
} for 1:
}
(for1- lần 3)i++➔i=1+1=2, kiểm tra i<n-1
i<5-12<4➔đúng

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 45


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


for 2:
void BubbleSort(int M[], int n) (for2- lần 1)Khởi tạo j=n-1=4, kiểm tra
{ j>i 4>2➔đúng
int i, j;
for (i = 0; i < n - 1; i++) If: M[j] <M[j-1]M[4]<M[3]
{
for (j = n - 1; j > i; j--)
60<35➔sai➔không đổi
{ vị trí, danh sách vẫn là:
if (M[j] < M[j - 1])// nếu
có nghịch thế M = {2,3,100,35,60};
{
int temp = M[j]; (for2- lần 2) j--➔j=4-1=3,
M[j] = M[j - 1]; kiểm tra j>i 3>2➔đúng
M[j - 1] = temp;
} If: M[j] <M[j-1]M[3]<M[2]
} 35<100➔đúng, hoán đổi vị
}
} trí của hai phần tử này, ta có:
M = {2,3,35,100,60};

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 46


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


(for2- lần 3) j--➔j=3-1=2,
kiểm tra j>i 2>2➔sai➔ngừng for 2
void BubbleSort(int M[], int n)
{ for 1:
int i, j; (for1- lần 4)i++➔i=2+1=3, kiểm tra i<n-1
for (i = 0; i < n - 1; i++)
{
i<5-13<4➔đúng
for (j = n - 1; j > i; j--) for 2:
{ (for2- lần 1)Khởi tạo j=n-1=4, kiểm tra
if (M[j] < M[j - 1])// nếu
có nghịch thế j>i 4>3➔đúng
{ If: M[j] <M[j-1]M[4]<M[3]
int temp = M[j];
M[j] = M[j - 1]; 60<100➔đúng, hoán đổi
M[j - 1] = temp; vị trí của hai phần tử này, ta có:
}
} M = {2,3,35,60,100};
}
} (for2- lần 2) j--➔j=4-1=3,
kiểm tra j>i 3>3➔sai➔ngừng for 2

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 47


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)


for 1:
void BubbleSort(int M[], int n) (for1- lần 5)i++➔i=3+1=4, kiểm tra i<n-1
{ i<5-14<4➔sai➔ngừng for 1
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--) ➔Kết thúc giải thuật BubbleSort, ta
{ được mảng sắp xếp dưới đây:
if (M[j] < M[j - 1])// nếu
có nghịch thế
{ M = {2,3,35,60,100};
int temp = M[j];
M[j] = M[j - 1];
M[j - 1] = temp;
}
}
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 48


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

Bài tập: Hãy giải thích từng bước quá trình chạy
Bubble Sort cho danh sách dưới đây:
int[] M = {10,15,2,8,7};
BubbleSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 49


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

Độ phức tạp của giải thuật Bubble Sort???


Tốt nhất O(???)

Xấu nhất O(???)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 50


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp nổi bọt (Bubble Sort)

➢Khuyết điểm:
 Không nhận diện được tình trạng dãy đã có thứ tự
hay có thứ tự từng phần.
 Các phần tử nhỏ được đưa về vị trí đúng rất nhanh,
trong khi các phần tử lớn lại được đưa về vị trí đúng
rất chậm.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 51


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp chọn


(Selection Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 52


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

 Mảng có thứ tự thì Mi=min(Mi, Mi+1, …, Mn-1)


 Ý tưởng: mô phỏng một trong những cách sắp xếp
tự nhiên nhất trong thực tế:
 Chọn phần tử nhỏ nhất trong N phần tử ban
đầu, đư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ử.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 53


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

 Bước 1 : i = 0;
 Bước 2 : Tìm phần tử M[min] nhỏ nhất trong dãy
hiện hành từ M[i] đến M[N-1]
 Bước 3 : Nếu min ≠ i, Hoán vị M[min] và M[i]

 Bước 4 : Nếu i < N-1 thì i = i+1; Lặp lại Bước 2

 Ngược lại: Dừng. //N-1 phần tử đã nằm đúng vị trí.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 54


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

• Ví dụ: sắp xếp dãy số sau


• 3,5,1,6,12,7,4,10,2

3 5 1 6 12 7 4 10 2

Nguồn minh họa: Thầy Trương Hoài Phan

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 55


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

3 5 1 6 12 7 4 10 2

i=0 min=2

1 5 3 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 56
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 5 3 6 12 7 4 10 2

i=1 min=8

1 2 3 6 12 7 4 10 5

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 57
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 6 12 7 4 10 5

i=min=2

1 2 3 6 12 7 4 10 5

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 58
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 6 12 7 4 10 5

i=3 min=6

1 2 3 4 12 7 6 10 5

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 59
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 4 12 7 6 10 5

i=4 min=8

1 2 3 4 5 7 6 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 60
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 4 5 7 6 10 12

i=5 min=6

1 2 3 4 5 6 7 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 61
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 4 5 6 7 10 12

i=min=6

1 2 3 4 5 6 7 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 62
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 4 5 6 7 10 12

i=min=7

1 2 3 4 5 6 7 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 63
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

1 2 3 4 5 6 7 10 12

i=min=8

1 2 3 4 5 6 7 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 64
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n)
{
int min;
for(int i=0;i<n-1;i++)
{
min = i; Giả sử số đầu trong dãy đang xét là nhỏ nhất
for(int j=i+1;j<n;j++)
{ Tìm số nhỏ nhất trong
if (M[j] < M[min]) dãy đang xét
min = j;
}
Nếu có số nào nhỏ hơn số đầu trong dãy
if(min!=i)
đang xét thì thay đổi vị trí cho nhau
{
int temp = M[i];
M[i] = M[min];
M[min] = temp;
}
}
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 65
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


Hãy giải thích từng bước quá trình chạy Selection
Sort cho danh sách dưới đây:
int M[5] = {100,3,60,35,2};
SelectionSort(M,n);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 66


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n)
{
int M[] = {100,3,60,35,2};
int min; SelectionSort(M);
for(int i=0;i<n-1;i++)
{ for 1:
min = i;
for(int j=i+1;j<n;j++)
(for1- lần 1)Khởi tạo i=0, kiểm tra i<n-1
{ i<5-10<4➔đúng:
if (M[j] < M[min])
min = j; min=i=0
}
if(min!=i) for 2:
{ (for2- lần 1)Khởi tạo j=i+1=1, kiểm tra
int temp = M[i];
M[i] = M[min]; j<n 1<5➔đúng
M[min] = temp;
} If: M[j] <M[min]M[1]<M[0]
}
}
3<100➔đúng:
min=j=1
(for2- lần 2) j++➔j=2, kiểm tra j<n
2<5➔đúng:

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 67


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n) If: M[j] <M[min]M[2]<M[1]
{
int min; 60<3➔sai
for(int i=0;i<n-1;i++) (for2- lần 3) j++➔j=3, kiểm tra j<n
{
min = i; 3<5➔đúng:
for(int j=i+1;j<n;j++)
{
If: M[j] <M[min]M[3]<M[1]
if (M[j] < M[min]) 35<3➔sai
min = j;
}
(for2- lần 4) j++➔j=4, kiểm tra j<n
if(min!=i) 4<5➔đúng:
{
int temp = M[i]; If: M[j] <M[min]M[4]<M[1]
M[i] = M[min];
M[min] = temp;
2<3➔đúng:
} min=j=4
} (for2- lần 5) j++➔j=5, kiểm tra j<n
}
5<5➔sai➔kết thúc for 2
If: min != i4!=0 ➔đúng ➔
hoán đổi vị trí 0 và 4 ta được:
M = {2,3,60,35,100};
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 68
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n) for 1:
{
int min; (for1- lần 2) i++➔i=1, kiểm tra i<n-1
for(int i=0;i<n-1;i++) i<5-11<4➔đúng:
{
min = i; min=i=1
for(int j=i+1;j<n;j++)
{ for 2:
if (M[j] < M[min]) (for2- lần 1)Khởi tạo j=i+1=2, kiểm tra
min = j;
} j<n 2<5➔đúng:
if(min!=i)
{ If: M[j] <M[min]M[2]<M[1]
int temp = M[i];
M[i] = M[min]; 60<3➔sai
M[min] = temp; (for2- lần 2) j++➔j=3, kiểm tra j<n
}
}
3<5➔đúng:
} If: M[j] <M[min]M[3]<M[1]
35<3➔sai
(for2- lần 3) j++➔j=4, kiểm tra j<n
4<5➔đúng:
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 69
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n)
{ If: M[j] <M[min]M[4]<M[1]
int min;
for(int i=0;i<n-1;i++)
100<3➔sai
{ (for2- lần 4) j++➔j=5, kiểm tra j<n
min = i;
for(int j=i+1;j<n;j++) 5<5➔sai➔kết thúc for 2
{
if (M[j] < M[min]) If: min != i1!=1 ➔sai ➔ giữ
}
min = j; nguyên mảng vì không thay đổi:
if(min!=i)
{
M = {2,3,60,35,100};
int temp = M[i]; for 1:
M[i] = M[min];
M[min] = temp;
(for1 - lần 3) i++➔i=2, kiểm tra i<n-1
} i<5-12<4➔đúng:
}
} min=i=2
for 2:
(for2- lần 1)Khởi tạo j=i+1=3, kiểm tra
j<n 3<5➔đúng:

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 70


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n)
{ If: M[j] <M[min]M[3]<M[2]
int min;
for(int i=0;i<n-1;i++)
35<60➔đúng:
{ min=j=3
min = i;
for(int j=i+1;j<n;j++)
(for2- lần 2) j++➔j=4, kiểm tra j<n
{ 4<5➔đúng:
if (M[j] < M[min])
min = j; If: M[j] <M[min]M[4]<M[3]
}
if(min!=i)
100<35➔sai
{ (for2- lần 3) j++➔j=5, kiểm tra j<n
int temp = M[i];
M[i] = M[min];
5<5➔sai➔dừng for 2
M[min] = temp;
} If: min != i3!=2 ➔ đúng ➔
}
}
hoán đổi vị trí 3 và 2 ta được:
M = {2,3,35,60,100};

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 71


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n) for 1:
{
int min; (for1 - lần 4) i++➔i=3, kiểm tra i<n-1
for(int i=0;i<n-1;i++) 3<5-13<4➔đúng:
{
min = i; min=i=3
for(int j=i+1;j<n;j++)
{ for 2:
if (M[j] < M[min]) (for2- lần 1)Khởi tạo j=i+1=4, kiểm tra
min = j;
} j<n 4<5➔đúng:
if(min!=i)
{
If: M[j] <M[min]M[4]<M[3]
int temp = M[i]; 100<60➔sai
M[i] = M[min];
M[min] = temp; (for2- lần 2) j++➔j=5, kiểm tra j<n
} 5<5➔sai➔dừng for 2
}
}
If: min != i3!=3 ➔ sai ➔ giữ
nguyên mảng cũ vì không đổi gì:
M = {2,3,35,60,100};
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 72
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)


void SelectionSort(int M[], int n) for 1:
{
int min; (for1 - lần 5) i++ ➔ i=4,
for(int i=0;i<n-1;i++) kiểm tra i < M.Length-1  4<5-1
{
min = i;
4<4➔sai➔dừng for 1
for(int j=i+1;j<n;j++)
{
if (M[j] < M[min])
min = j; Kết thúc giải thuật ta có:
}
if(min!=i)
{
int temp = M[i];
M = {2,3,35,60,100};
M[i] = M[min];
M[min] = temp;
}
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 73


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

Bài tập: Hãy giải thích từng bước quá trình chạy
Selection Sort cho danh sách dưới đây:
Int M[] = {10,15,2,8,7};
SelectionSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 74


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

❑ Đánh giá giải thuật:


 Ở lượt thứ i, cần (n-i) lần so sánh để xác định phần tử
nhỏ nhất hiện hành.
 Số lượng phép so sánh không phụ thuộc vào tình
trạng của dãy số ban đầu.
 Trong mọi trường hợp, số lần so sánh là :

n −1
n(n − 1)

i =1
n−i =
2
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 75
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chọn trực tiếp (Selection Sort)

 Đánh giá giải thuật:


 Số lần hoán vị (một hoán vị bằng 3 phép gán)
phụ thuộc vào tình trạng ban đầu của dãy số

Trường hợp số lần so sánh số lần gán

Tốt nhất N(N-1)/2 0


Xấu nhất N(N-1)/2 3N

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 76


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp chèn


(Insertion Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 77


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 78


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 79


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

• Xét dãy n phần tử: M0, M1,…, Mn-1


• Xem dãy gồm 1 phần tử là M0 dãy có thứ tự
• Thêm M1 vào dãy có thứ tự M0 sao cho dãy mới M0,
M1 là dãy có thứ tự. Nếu M1 <M0 ta đổi chỗ M1 với
M0.
• Thêm M2 vào dãy có thứ tự M0, M1 sao cho dãy mới
M0, M1, M2 là dãy có thứ tự
• Tiếp tục như thế đến n-1 bước ta sẽ có dãy có thứ tự
M0, M1, …., Mn-1

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 80


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

• Bước 1: i = 1; // giả sử có đoạn M[0] đã được sắp


• Bước 2: x = M[i]; Tìm vị trí pos thích hợp trong
đoạn M[0] đến M[i-1] để chèn M[i] vào
• Bước 3: Dời chỗ các phần tử từ M[pos] đến M[i-1]
sang phải 1 vị trí để dành chỗ cho M[i]
• Bước 4: M[pos] = x; // có đoạn M[0]..M[i-1] đã được
sắp
• Bước 5: i = i+1;
Nếu i < n : Lặp lại Bước 2.
Ngược lại : Dừng.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 81


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

Ví dụ: sắp xếp dãy số sau


3,5,1,6,12,7,4,10,2

3 5 1 6 12 7 4 10 2

Nguồn minh họa: Thầy Trương Hoài Phan

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 82
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

3 5 1 6 12 7 4 10 2

i=1

3 5 1 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 83
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

i=2

3 5 1 6 12 7 4 10 2

1 3 5 6 12 7 4 10 2

1 3 5 6 12 7 4 10 2

1 3 5 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 84
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

1 3 5 6 12 7 4 10 2

i=3

1 3 5 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 85
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

1 3 5 6 12 7 4 10 2

i=4

1 3 5 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 86
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

i=5

1 3 5 6 12 7 4 10 2

7 1 3 5 6 12 4 10 2

1 3 5 6 7 12 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 87
Khoa Hệ Thống Thông Tin Quản lý
Phương pháp chèn trực tiếp (Insertion Sort)
i=6

1 3 5 6 7 12 4 10 2

4 1 3 5 6 7 12 10 2

4 1 3 5 6 7 12 10 2

4 1 3 5 6 7 12 10 2

4 1 3 5 6 7 12 10 2

1 3 4 5 6 7 12 10 2
0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 88
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

i=7

1 3 4 5 6 7 12 10 2

10 1 3 4 5 6 7 12 2

1 3 4 5 6 7 10 12 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 89
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

1 3 4 5 6 7 10 12 2

i=7

1 2 3 4 5 6 7 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 90
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


void InsertionSort(int M[], int n)
{
//lưu vị trí cần chèn
int pos=0;
int x;
//xem đoạn M[0] đã sắp
for (int i = 1; i < n; i++)
{
x = M[i]; //lưu trữ giá trị M[i] tránh bị ghi đè khi dời chỗ các phần tử.

for (pos = i; (pos > 0) && (M[pos - 1] > x); pos--)


{
M[pos] = M[pos - 1];
}
M[pos] = x;// chèn x vào dãy
}
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 91
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


Hãy giải thích từng bước quá trình chạy Insertion
Sort cho danh sách dưới đây:
int[] M = {100,3,60,35,2};
InsertionSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 92


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


int[] M = {100,3,60,35,2};
void InsertionSort(int M[], int n) InsertionSort(M);
{ Khởi tạo pos =0
//lưu vị trí cần chèn
int pos=0; for 1:
//lưu trữ giá trị M[i] tránh bị (for1- lần 1)Khởi tạo i=1, kiểm tra i<n
ghi đè khi dời chỗ các phần tử. 1<5➔đúng:
int x;
//xem đoạn M[0] đã sắp
x=M[i]=M[1]=3
for (int i = 1; i < n; i++) for 2:
{
x = M[i];
(for2- lần 1)Khởi tạo pos=i=1, kiểm tra
for (pos = i; (pos > 0) && pos>0 và M[pos-1]>x 1>0 và
(M[pos - 1] > x); pos--) M[0]>31>0 && 100>3➔đúng:
{
M[pos] = M[pos - 1]; M[pos]=M[pos-1]
} M[1]=M[1-1]=M[0]=100
M[pos] = x;// chèn x vào dãy
} ➔M = {100,100,60,35,2}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 93


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


for 2:
(for2- lần 2) pos--➔pos=0, kiểm tra
void InsertionSort(int M[], int n)
pos>0 và M[pos-1]>x 0>0➔sai, ngừng
{
//lưu vị trí cần chèn for 2.
int pos=0; M[pos]=x M[0]=3
//lưu trữ giá trị M[i] tránh bị ➔M = {3,100,60,35,2}
ghi đè khi dời chỗ các phần tử. for 1:
int x; (for1- lần 2) i++ ➔ i=2, kiểm tra i<n
//xem đoạn M[0] đã sắp
for (int i = 1; i < n; i++) 2<5➔đúng:
{ x=M[i]=M[2]=60
x = M[i]; for 2:
for (pos = i; (pos > 0) &&
(M[pos - 1] > x); pos--) (for2- lần 1) Khởi tạo pos=i=2, kiểm tra
{ pos>0 và M[pos-1]>x 2>0 và M[1]>60
M[pos] = M[pos - 1]; 2>0 && 100>60➔đúng:
}
M[pos] = x;// chèn x vào dãy M[pos]=M[pos-1]
} M[2]=M[2-1]=M[1]=100
}
➔M = {3,100,100,35,2}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 94
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


for 2:
(for2- lần 2) pos--➔pos=1, kiểm tra
void InsertionSort(int M[], int n) pos>0 và M[pos-1]>x 1>0 &&
{ M[0]>601>0 && 3 >60➔sai, ngừng
//lưu vị trí cần chèn
int pos=0; for 2.
//lưu trữ giá trị M[i] tránh bị M[pos]=x M[1]=60
ghi đè khi dời chỗ các phần tử. ➔M = {3,60,100,35,2}
int x; for 1:
//xem đoạn M[0] đã sắp (for1- lần 3) i++ ➔ i=3, kiểm tra i<n
for (int i = 1; i < n; i++)
{ 3<5➔đúng:
x = M[i]; x=M[i]=M[3]=35
for (pos = i; (pos > 0) && for 2:
(M[pos - 1] > x); pos--) (for2- lần 1) Khởi tạo pos=i=3, kiểm tra
{
M[pos] = M[pos - 1]; pos>0 và M[pos-1]>x 3>0 và M[2]>35
} 3>0 && 100>35➔đúng:
M[pos] = x;// chèn x vào dãy M[pos]=M[pos-1]
} M[3]=M[3-1]=M[2]=100
}
➔M = {3,60,100,100,2}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 95
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


for 2:
(for2- lần 2) pos--➔pos=2, kiểm tra
void InsertionSort(int M[], int n) pos>0 và M[pos-1]>x 2>0 &&
{ M[1]>352>0 && 60 >35➔Đúng:
//lưu vị trí cần chèn
int pos=0; M[pos]=M[pos-1]
//lưu trữ giá trị M[i] tránh bị M[2]=M[2-1]=M[1]=60
ghi đè khi dời chỗ các phần tử.
int x;
➔M = {3,60,60,100,2}
//xem đoạn M[0] đã sắp for 2:
for (int i = 1; i < n; i++) (for2- lần 3) pos--➔pos=1, kiểm tra
{ pos>0 và M[pos-1]> x 1>0 && M[0]>35
x = M[i];
for (pos = i; (pos > 0) &&
1>0 && 3 >35➔sai, dừng for 2.
(M[pos - 1] > x); pos--) M[pos]=x M[1]=35
{
M[pos] = M[pos - 1]; ➔M = {3,35,60,100,2}
} for 1:
M[pos] = x;// chèn x vào dãy (for1- lần 4) i++ ➔ i=4, kiểm tra i<n
} 4<5➔đúng:
}
x=M[i]=M[4]=2
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 96
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


for 2:
(for2- lần 1) Khởi tạo pos=i=4, kiểm tra
void InsertionSort(int M[], int n)
pos>0 và M[pos-1]>x 4>0 và M[3]>2
{
//lưu vị trí cần chèn 4>0 && 100>2➔đúng:
int pos=0; M[pos]=M[pos-1]
//lưu trữ giá trị M[i] tránh bị
ghi đè khi dời chỗ các phần tử.
M[4]=M[4-1]=M[3]=100
int x; ➔M = {3,35,60,100,100}
//xem đoạn M[0] đã sắp
for (int i = 1; i < n; i++) for 2:
{ (for2- lần 2) pos--➔pos=3, kiểm tra
x = M[i];
pos>0 và M[pos-1]> x 3>0 && M[2]>2
for (pos = i; (pos > 0) &&
(M[pos - 1] > x); pos--) 3>0 && 60 >2➔đúng:
{ M[pos]=M[pos-1]
M[pos] = M[pos - 1];
} M[3]=M[3-1]=M[2]=60
M[pos] = x;// chèn x vào dãy
} ➔M = {3,35,60,60,100}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 97


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


for 2:
(for2- lần 3) pos--➔pos=2, kiểm tra
void InsertionSort(int M[], int n)
pos>0 và M[pos-1]> x 2>0 && M[1]>2
{
//lưu vị trí cần chèn 2>0 && 35 >2➔đúng:
int pos=0; M[pos]=M[pos-1]
//lưu trữ giá trị M[i] tránh bị
ghi đè khi dời chỗ các phần tử. M[2]=M[2-1]=M[1]=35
int x;
//xem đoạn M[0] đã sắp ➔M = {3,35,35,60,100}
for (int i = 1; i < n; i++) for 2:
{
x = M[i];
(for2- lần 4) pos--➔pos=1, kiểm tra
for (pos = i; (pos > 0) && pos>0 và M[pos-1]> x 1>0 && M[0]>2
(M[pos - 1] > x); pos--) 1>0 && 3 >2➔đúng:
{
M[pos] = M[pos - 1]; M[pos]=M[pos-1]
} M[1]=M[1-1]=M[0]=3
M[pos] = x;// chèn x vào dãy
} ➔M = {3,3,35,60,100}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 98


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


for 2:
void InsertionSort(int M[], int n)
(for2- lần 5) pos--➔pos=0, kiểm tra
{ pos>0 và M[pos-1]> x 0>0 ➔sai, dừng
//lưu vị trí cần chèn for 2.
int pos=0;
//lưu trữ giá trị M[i] tránh bị M[pos]=x M[0]=2
ghi đè khi dời chỗ các phần tử.
int x;
➔M = {2,3,35,60,100}
//xem đoạn M[0] đã sắp for 1:
for (int i = 1; i < n; i++) (for1- lần 5) i++ ➔ i=5, kiểm tra i<n
{
x = M[i];
5<5➔sai, dừng for 1:
for (pos = i; (pos > 0) && Vậy kết thúc giải thuật ta được mảng:
(M[pos - 1] > x); pos--)
{
M[pos] = M[pos - 1];
➔M = {2,3,35,60,100}
}
M[pos] = x;// chèn x vào dãy
}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 99


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

Bài tập 1: Hãy giải thích từng bước quá trình chạy
Insertion Sort cho danh sách dưới đây:
int[] M = {10,8,20,81,25};
InsertionSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 100


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

Bài tập 2: Cho danh sách Sinh viên, mỗi Sinh viên có
các thông số: Mã(int), tên(chuỗi), ngày sinh
(DateTime)
- Hãy xây dựng cấu trúc dữ liệu cho mô tả trên
- Hãy viết giải thuật Insertion Sort để: Sắp xếp theo
tên tăng dần, nếu tên trùng nhau thì sắp xếp theo
ngày sinh giảm dần.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 101


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)


❑Đánh giá giải thuật:
• Các phép so sánh xảy ra trong mỗi vòng lặp tìm vị
trí thích hợp pos, và mỗi lần xác định vị trí đang xét
không thích hợp, sẽ dời chỗ phần tử M[pos] tương
ứng.
• Giải thuật thực hiện tất cả N-1 vòng lặp tìm pos, do
số lượng phép so sánh và dời chỗ này phụ thuộc vào
tình trạng của dãy số ban đầu, nên chỉ có thể ước
lượng trong từng trường hợp như sau (tương đối):

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 102


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp chèn trực tiếp (Insertion Sort)

❑Nhận xét:
• Khi tìm vị trí thích hợp để chèn M[i] vào đoạn M[0]
đến M[i-1], do đoạn đã được sắp, nên có thể sử dụng
giải thuật tìm nhị phân để thực hiện việc tìm vị trí
pos, khi đó có giải thuật sắp xếp chèn nhị phân
Binary Insertion Sort

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 103


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp đổi chỗ


(Interchange Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 104


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp (Interchange Sort)

➢ Để sắp xếp một dãy số, ta có thể xét các nghịch thế
có trong dãy và làm triệt tiêu dần chúng đi.
➢ Ý tưởng chính:
– Xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa
phần tử này, triệt tiêu chúng bằng cách đổi chỗ
phần tử này với phần tử tương ứng trong cặp
nghịch thế.
– Lặp lại xử lý trên với các phần tử tiếp theo trong
dãy

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 105


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

 Bước 1 : i = 0;// bắt đầu từ đầu dãy


 Bước 2 : j = i+1;//tìm các phần tử M[j] < M[i], j>i

 Bước 3 :

 Trong khi j ≤ N thực hiện


 Nếu M[j]<M[i]: M[i]↔M[j];//xét cặp phần tử M[i],
M[j]
 j = j+1;
 Bước 4 : i = i+1;

 Nếu i < n: Lặp lại Bước 2.


 Ngược lại: Dừng.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 106


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

Ví dụ: sắp xếp dãy số sau


3,5,1,6,12,7,4,10,2

3 5 1 6 12 7 4 10 2

Nguồn minh họa: Thầy Trương Hoài Phan

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 107
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

3 5 1 6 12 7 4 10 2

i=0 j=2

1 5 3 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 108
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 5 3 6 12 7 4 10 2

i=1 j=2

1 3 5 6 12 7 4 10 2

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 109
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 3 5 6 12 7 4 10 2

i=1 j=8

1 2 5 6 12 7 4 10 3

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 110
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 5 6 12 7 4 10 3

i=2 j=6

1 2 4 6 12 7 5 10 3

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 111
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 4 6 12 7 5 10 3

i=2 j=8

1 2 3 6 12 7 5 10 4

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 112
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 6 12 7 5 10 4

i=3 j=6

1 2 3 5 12 7 6 10 4

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 113
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 5 12 7 6 10 4

i=3 j=8

1 2 3 4 12 7 6 10 5

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 114
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 12 7 6 10 5

i=4 j=5

1 2 3 4 7 12 6 10 5

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 115
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 7 12 6 10 5

i=4 j=6

1 2 3 4 6 12 7 10 5

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 116
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 6 12 7 10 5

i=4 j=8

1 2 3 4 5 12 7 10 6

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 117
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 5 12 7 10 6

i=5 j=6

1 2 3 4 5 7 12 10 6

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 118
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 5 7 12 10 6

i=5 j=8

1 2 3 4 5 6 12 10 7

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 119
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 5 6 12 10 7

i=5 j=7

1 2 3 4 5 6 10 12 7

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 120
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 5 6 10 12 7

i=5 j=8

1 2 3 4 5 6 7 12 10

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 121
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

1 2 3 4 5 6 7 12 10

i=7 j=8

1 2 3 4 5 6 7 10 12

0 1 2 3 4 5 6 7 8
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 122
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


void InterchangeSort(int[] M, int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if (M[j] < M[i])
{
int temp = M[i];
M[i] = M[j];
M[j] = temp;
}
}
}
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 123
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


Hãy giải thích từng bước quá trình chạy Interchange
Sort cho danh sách dưới đây:
int[] M = {100,3,60,35,2};
InterchangeSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 124


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


int[] M = {100,3,60,35,2};
void InterchangeSort(int[] M, int n)
{ InterchangeSort(M);
int i, j;
for (i = 0; i < n - 1; i++) for 1:
{ (for1- lần 1)Khởi tạo i=0, kiểm tra i<n-1
for (j = i + 1; j < n; j++)
{
0<4➔đúng:
if (M[j] < M[i])
{
for 2:
int temp = M[i]; (for2- lần 1)Khởi tạo j=i+1=1, kiểm
M[i] = M[j]; tra j<n 1<5➔đúng:
M[j] = temp;

}
} If: M[j] <M[i] M[1]<M[0]
} 3<100➔đúng➔ hoán đổi vị
}
trí 0 và 1 ta được mảng mới:
M = {3,100,60,35,2}
(for2- lần 2) j++➔j=2, kiểm tra j<n
2<5➔đúng:

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 125


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


If: M[j] <M[i] M[2]<M[0]
void InterchangeSort(int[] M) 60<3➔sai➔ mảng vẫn giữ :
{
int i, j; M = {3,100,60,35,2}
for (i = 0; i < M.Length - 1; i++)
{ (for2- lần 3) j++➔j=3, kiểm tra j<n
for (j = i + 1; j < M.Length; j++)
{
3<5➔đúng:
if (M[j] < M[i])
{ If: M[j] <M[i] M[3]<M[0]
int temp = M[i]; 35<3➔sai➔ Mảng vẫn giữ:
M[i] = M[j];
M[j] = temp; M = {3,100,60,35,2}
}
} (for2- lần 4) j++➔j=4, kiểm tra j<n
}
}
4<5➔đúng:
If: M[j] <M[i] M[4]<M[0]
2<3➔đúng➔ hoán đổi vị trí
0 và 4 ta được mảng mới:
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 126
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


M = {2,100,60,35,3}
void InterchangeSort(int[] M)
{
(for2- lần 5) j++➔j=5, kiểm
int i, j; tra j<n 5<5➔sai, dừng for 2:
for (i = 0; i < M.Length - 1; i++)
{
for (j = i + 1; j < M.Length; j++)
for 1:
{ (for1- lần 2) i++ ➔i=1, kiểm tra
if (M[j] < M[i])
{
i<n-1 1<4➔đúng:
int temp = M[i]; for 2:
M[i] = M[j]; (for2- lần 1)Khởi tạo j=i+1=2,
M[j] = temp;
} kiểm tra j<n 2<5➔đúng:
}

}
}
If: M[j] <M[i] M[2]<M[1]
60<100➔đúng➔hoán đổi vị
trí 1 và 2 ta được mảng mới:
M = {2,60,100,35,3}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 127
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


(for2- lần 2)j++➔ j=3, kiểm tra
void InterchangeSort(int[] M) j<n 3<5➔đúng:
{
int i, j; If: M[j] <M[i] M[3]<M[1]
for (i = 0; i < M.Length - 1; i++)
{ 35<60➔đúng➔hoán đổi vị
for (j = i + 1; j < M.Length; j++) trí 3 và 1 ta được mảng mới:
{
if (M[j] < M[i]) M = {2,35,100,60,3}
{
int temp = M[i]; (for2- lần 3)j++➔ j=4, kiểm tra
M[i] = M[j];
M[j] = temp;
j<n 4<5➔đúng:
} If: M[j] <M[i] M[4]<M[1]
}
} 3<35➔đúng➔hoán đổi vị trí
} 4 và 1 ta được mảng mới:
M = {2,3,100,60,35}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 128


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


(for2- lần 4)j++➔ j=5, kiểm tra
void InterchangeSort(int[] M) j<n 5<5➔sai, dừng for 2.
{
int i, j;
for (i = 0; i < M.Length - 1; i++) for 1:
{
for (j = i + 1; j < M.Length; j++) (for1- lần 3) i++ ➔i=2, kiểm tra
{ i<n-1 2<4➔đúng:
if (M[j] < M[i])
{ for 2:
int temp = M[i];
M[i] = M[j]; (for2- lần 1)Khởi tạo j=i+1=3,
M[j] = temp; kiểm tra j<n 3<5➔đúng:
}
}

}
}
If: M[j] <M[i] M[3]<M[2]
60<100➔đúng➔hoán đổi vị
trí 3 và 2 ta được mảng mới:
M = {2,3,60,100,35}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 129
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


(for2- lần 2) j++➔j=4, kiểm tra
void InterchangeSort(int[] M) j<n 4<5➔đúng:
{
int i, j; If: M[j] <M[i] M[4]<M[2]
for (i = 0; i < M.Length - 1; i++)
{
35<60➔đúng➔hoán đổi vị
for (j = i + 1; j < M.Length; j++) trí 4 và 2 ta được mảng mới:
{
if (M[j] < M[i]) M = {2,3,35,100,60}
{
int temp = M[i]; (for2- lần 3) j++➔j=5, kiểm tra
M[i] = M[j];
M[j] = temp; j<n 5<5➔sai, dừng for 2.
}
}
} for 1:
}
(for1- lần 4) i++ ➔i=3, kiểm tra
i<n-1 3<4➔đúng:

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 130


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)


for 2:
void InterchangeSort(int[] M) (for2- lần 1)Khởi tạo j=i+1=4,
{
int i, j; kiểm tra j<n 4<5➔đúng:
for (i = 0; i < M.Length - 1; i++)
{
for (j = i + 1; j < M.Length; j++) If: M[j] <M[i] M[4]<M[3]
{
if (M[j] < M[i])
60<100➔đúng➔hoán đổi vị
{ trí 4 và 3 ta được mảng mới:
int temp = M[i];
M[i] = M[j]; M = {2,3,35,60,100}
M[j] = temp; (for2- lần 2) j++➔j=5, kiểm tra
}
}
j<n 5<5➔sai, dừng for 2.
}
} for 1:
(for1- lần 5) i++ ➔i=4, kiểm
tra i<n-14<4➔sai, dừng :
M = {2,3,35,60,100}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 131
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

Bài tập 1: Hãy giải thích từng bước quá trình chạy
Interchange Sort cho danh sách dưới đây:
int[] M = {90,95,20,27,30};
InterchangeSort(M);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 132


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

Bài tập 2: Cho danh sách Sinh viên, mỗi Sinh viên có
các thông số: Mã(int), tên(chuỗi), ngày sinh
(DateTime)
- Hãy xây dựng cấu trúc dữ liệu bằng class cho mô
tả trên
- Hãy viết giải thuật Interchange Sort để: Sắp xếp
theo tên tăng dần, nếu tên trùng nhau thì sắp xếp
theo ngày sinh giảm dần.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 133


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp đổi chỗ trực tiếp(Interchange Sort)

➢ Đánh giá giải thuật:


• Số lượng các phép so sánh xảy ra không phụ thuộc
vào tình trạng của dãy số ban đầu
• Số lượng phép hoán vị thực hiện tùy thuộc vào kết
quả so sánh

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 134


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp nhanh


(Quick Sort)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 135


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

➢ Ðể sắp xếp dãy M0, M1, ..., Mn-1 giải thuật QuickSort dựa
trên việc phân hoạch dãy ban đầu thành hai phần :
➢ Dãy con 1: Gồm các phần tử M0.. Mi có giá trị không lớn
hơn pivot
➢ Dãy con 2: Gồm các phần tử Mi .. Mn-1 có giá trị không nhỏ
hơn pivot
➢ với pivot là giá trị của một phần tử tùy ý trong dãy ban
đầu. Sau khi thực hiện phân hoạch, dãy ban đầu được phân
thành 3 phần:
1. Mk < pivot , với k = 0..i
2. Mk = pivot , với k = i..j
3. Mk > pivot , với k = j..N-1

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 136


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

Mk<pivot Mk=pivot Mk>pivot

0 i j N-1

➢ Trong đó dãy con thứ 2 đã có thứ tự,


➢ Nếu các dãy con 1 và 3 chỉ có 1 phần tử thì chúng cũng
đã có thứ tự, khi đó dãy ban đầu đã được sắp.
➢ Ngược lại, nếu các dãy con 1 và 3 có nhiều hơn 1 phần
tử thì dãy ban đầu chỉ có thứ tự khi các dãy con 1, 3
được sắp.
➢ Ðể sắp xếp dãy con 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 .

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 137


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


Giải thuật phân hoạch dãy Ml, Ml+1, ., Mr thành 2 dãy con:
• Bước 1 : Chọn tùy ý một phần tử M[k] trong dãy là giá trị
mốc, l ≤ k ≤ r:
pivot = M[k]; i = l; j = r;
• Bước 2 : Phát hiện và hiệu chỉnh cặp phần tử M[i], M[j] nằm
sai chỗ :
• Bước 2a : Trong khi (M[i]<x) i++;
• Bước 2b : Trong khi (M[j]>x) j--;
• Bước 2c : Nếu i<= j // M[i] ≥ pivot ≥ M[j] mà M[j] đứng sau M[i]
Hoán vị (M[i],M[j]);
• Bước 3 :
Nếu i < j: Lặp lại Bước 2.//chưa xét hết mảng
Nếu i ≥ j: Dừng

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 138


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


➢ Về nguyên tắc, có thể chọn giá trị mốc pivot là một phần tử
tùy ý trong dãy, nhưng để đơn giản, dễ diễn đạt giải thuật,
phần tử có vị trí giữa thường được chọn, khi đó k = (l +r)/ 2
➢ Giá trị mốc pivot được chọn sẽ có tác động đến hiệu quả
thực hiện thuật toán vì nó quyết định số lần phân hoạch. Số
lần phân hoạch sẽ ít nhất nếu ta chọn được pivot là phần tử
median của dãy. Tuy nhiên do chi phí xác định phần tử
median quá cao nên trong thực tế người ta không chọn phần
tử này mà chọn phần tử nằm chính giữa dãy làm mốc với hy
vọng nó có thể gần với giá trị median

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 139


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

Giải thuật phân hoạch dãy sắp xếp dãy Ml, Ml+1, ., Mr:
Có thể phát biểu giải thuật sắp xếp QuickSort một cách đệ qui
như sau :
➢ Bước 1 : Phân hoạch dãy Ml .. Mr thành các dãy con :
- Dãy con 1 : Ml.. Mj ≤ x
- Dãy con 2 : Mj+1.. Mi-1 = pivot
- Dãy con 3 : Mi.. Mr ≥ pivot
➢ Bước 2 :
Nếu ( l < j ) // dãy con 1 có nhiều hơn 1 phần tử
Phân hoạch dãy Ml.. Mj
Nếu ( i < r ) // dãy con 3 có nhiều hơn 1 phần tử
Phân hoạch dãy Mi.. Mr

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 140


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

Minh họa sắp xếp M={3,5,33,1,8,12,4,23,8}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 141


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

• Sắp xếp bộ dữ liệu


• 1,5,3,6,7,12,4,10,2,9

1 5 3 6 7 12 4 10 2 9

Phân hoạch đoạn 7

l=0 r=9, pivot=M[4]=7

0 1 2 3 4 5 6 7 8 9

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 142


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

Phân hoạch đoạn 7

l=0 r=9, pivot=M[4]=7

1 5 3 6 7 12 4 10 2 9

i j
L=0 R=9

1 5 3 6 2 12 4 10 7 9

0 1 2 3 4 5 6 7 8 9

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 143


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

Phân hoạch đoạn


7
l=0 r=9, pivot=M[4]=7

1 5 3 6 2 12 4 10 7 9

i j
L=0 R=9
Phân hoạch đoạn
l=0 r=9, pivot=M[4]=7
j i

1 5 3 6 2 4 12 10 7 9

0 1 2 3 4 5 6 7 8 9

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 144


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

1 5 3 6 2 4 12 10 7 9

Phân hoạch đoạn l=0 r=5, pivot=M[2]=3

L=0 R=5 L=6 R=9

J=i j i

1 2 3 6 5 4 9 7 10 12

0 1 2 3 4 5 6 7 8 9
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 145
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

1 2 3 6 5 4 9 7 10 12

1 2 3 4 5 6 7 9 10 12

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 146


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int M,int left, int right)
{
if (left >= right) return;
int pivot = M[(left + right) / 2];
int i = left, j = right ;
do{
while (M[i] < pivot) i++;
while (M[j] > pivot) j--;
if (i <= j){
int temp = M[i];
M[i] = M[j];
M[j] = temp;
i++;
j--;
}
} while (i < j);
QuickSort(M,left, j);
QuickSort(M,i,right);
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 147
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


Hãy giải thích từng bước quá trình chạy QuickSort
cho danh sách dưới đây:
int[] M = {100,3,60,35,2};
QuickSort(M,0,n-1);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 148


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) int[] M = {100,3,60,35,2};
{ QuickSort(M,0,M.Length-1);
if (left >= right) return;
int pivot = M[(left + right) / 2]; Quicksort lần 1:
int i = left, j = right ;
do{
QuickSort(M,0,4);
while (M[i] < pivot) i++; left =0, right=4
while (M[j] > pivot) j--; pivot=M[(left+right)/2]=M[2]=60
if (i <= j){
int temp = M[i]; i=0, j=4
M[i] = M[j]; Do –lần 1:
M[j] = temp;
i++; while 1:
j--; Lần 1: M[i] <pivotM[0] <60
} 100<60 sai➔dừng while 1
} while (i < j);
QuickSort(M,left, j); while 2:
QuickSort(M,i,right); Lần 1: M[j] >pivotM[4] >60
}
2>60 sai➔dừng while 2
If: i<=j  0<=4➔đúng:
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 149
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) ➔Hoán đổi vị trí 0 và 4, mảng mới:
{
if (left >= right) return; M = {2,3,60,35,100}
int pivot = M[(left + right) / 2]; i++➔i=1
int i = left, j = right ;
do{ j-- ➔j=3
while (M[i] < pivot) i++;
while (M[j] > pivot) j--;
While i<j 1<3➔đúng➔lặp lại do
if (i <= j){ Do –lần 2:
int temp = M[i]; while 1:
M[i] = M[j];
M[j] = temp; Lần 1: M[i] <pivotM[1] <60
i++; 3<60 đúng➔i++➔i=2
j--; Lần 2: M[i] <pivotM[2] <60
}
} while (i < j); 60<60 sai➔dừng while 1
QuickSort(M,left, j); while 2:
QuickSort(M,i,right);
}
Lần 1: M[j] >pivotM[3] >60
35>60 sai➔dừng while 2
If: i<=j  2<=3➔đúng:
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 150
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) ➔Hoán đổi vị trí 2 và 3, mảng mới:
{
if (left >= right) return; M = {2,3,35,60,100}
int pivot = M[(left + right) / 2]; i++➔i=3
int i = left, j = right ;
do{ j-- ➔j=2
while (M[i] < pivot) i++;
while (M[j] > pivot) j--;
While i<j 3<2➔sai➔dừng do
if (i <= j){ Quicksort lần 2 (đệ qui):
int temp = M[i];
M[i] = M[j]; QuickSort(M, left, j)
M[j] = temp; QuickSort(M, 0,2);
i++;
j--; ➔Lưu Stack
}
} while (i < j);
cho dòng lệnh i=3,right=4
QuickSort(M,left, j); cuối cùng
QuickSort(M,i,right); left =0, right=2
}
pivot=M[(left+right)/2]=M[1]=3
i=0, j=2
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 151
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) Do –lần 1: i=3,right=4
{ while 1:
if (left >= right) return;
int pivot = M[(left + right) / 2]; Lần 1: M[i] <pivotM[0] <3
int i = left, j = right ; 2<3 đúng➔i++➔i=1
do{
while (M[i] < pivot) i++;
Lần 2: M[i] <pivotM[1] <3
while (M[j] > pivot) j--; 3<3 sai➔dừng while 1
if (i <= j){ while 2:
int temp = M[i]; Lần 1: M[j] >pivotM[2] >3
M[i] = M[j];
M[j] = temp; 35>3 đúng➔j--➔j=1
i++; Lần 2: M[j] >pivotM[1] >3
j--; 3>3 sai➔dừng while 2
}
If: i<=j  1<=1➔đúng:
} while (i < j);
QuickSort(M,left, j); ➔Hoán đổi vị trí 1 và 1, mảng ko đổi:
QuickSort(M,i,right); M = {2,3,35,60,100}
} i++➔i=2
j-- ➔j=0
While i<j 2<0➔sai➔dừng do
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 152
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) Quicksort lần 3 (đệ qui):
{
if (left >= right) return; QuickSort(M, left, j)
int pivot = M[(left + right) / 2]; QuickSort(M, 0,0);
int i = left, j = right ; i=2,right=2
do{ ➔Lưu Stack
while (M[i] < pivot) i++; cho dòng lệnh
while (M[j] > pivot) j--; cuối cùng i=3,right=4
if (i <= j){
int temp = M[i]; left =0, right=0
M[i] = M[j]; if: left>=right 0>=0 return➔
M[j] = temp;
i++;
ngừng đệ qui➔gọi Stack
j--; Quicksort lần 4 (gọi stack):
}
} while (i < j); QuickSort(M, i, right)
QuickSort(M,left, j); QuickSort(M, 2,2);
QuickSort(M,i,right);
} left =2, right=2
If: 2>=2 ➔ ngừng đệ i=3,right=4
qui➔gọi Stack
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 153
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) Quicksort lần 5 (gọi stack):
{
if (left >= right) return;
QuickSort(M, i, right)
int pivot = M[(left + right) / 2]; QuickSort(M, 3,4);
int i = left, j = right ;
do{
left =3, right=4
while (M[i] < pivot) i++; pivot=M[(left+right)/2]=M[3]=60
while (M[j] > pivot) j--; i=3, j=4
if (i <= j){
int temp = M[i]; Do –lần 1:
M[i] = M[j]; while 1:
M[j] = temp;
i++;
Lần 1: M[i] <pivotM[3] <60
j--; 60<60 sai➔dừng while 1
} while 2:
} while (i < j); Lần 1: M[j] >pivotM[4] >60
QuickSort(M,left, j);
QuickSort(M,i,right);
100>60 đúng➔j--➔j=3
} Lần 2: M[j] >pivotM[3] >60
60>60 sai➔dừng while 2
If: i<=j  3<=3➔đúng:
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 154
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) ➔Hoán đổi vị trí 3 và 3, mảng ko đổi:
{
if (left >= right) return; M = {2,3,35,60,100}
int pivot = M[(left + right) / 2]; i++➔i=4
int i = left, j = right ;
do{ j-- ➔j=2
while (M[i] < pivot) i++;
while (M[j] > pivot) j--;
While i<j 4<2➔sai➔dừng do
if (i <= j){ Quicksort lần 6 (đệ qui):
int temp = M[i];
M[i] = M[j]; QuickSort(M, left, j)
M[j] = temp; QuickSort(M, 3,2);
i++;
j--; ➔Lưu Stack i=4,right=4
}
} while (i < j);
cho dòng lệnh
QuickSort(M,left, j); cuối cùng
QuickSort(M,i,right); left =3, right=2
}
If: left>=right 3>=2➔ngừng đệ
qui➔gọi Stack
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 155
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)


void QuickSort(int []M,int left, int right) Quicksort lần 7 (gọi stack):
{
if (left >= right) return;
QuickSort(M, i, right)
int pivot = M[(left + right) / 2]; QuickSort(M, 4,4);
int i = left, j = right ;
do{
while (M[i] < pivot) i++;
while (M[j] > pivot) j--; left =4, right=4
if (i <= j){ If: left>=right 4>=4➔ngừng đệ
int temp = M[i]; qui➔kiểm tra thấy Stack rỗng➔kết
M[i] = M[j];
M[j] = temp; thúc giải thuật QuickSort
i++;
j--;
}
Kết thúc giải thuật QuickSort ta
} while (i < j); được mảng mới:
QuickSort(M,left, j);
QuickSort(M,i,right); M = {2,3,35,60,100}
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 156


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

Bài tập: Hãy giải thích từng bước quá trình chạy
Quick Sort cho danh sách dưới đây:
int[] M = {5,2,27,200,2};
QuickSort(M,0,n-1);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 157


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp nhanh (Quick Sort)

➢Đánh giá thuật toán


Trường hợp độ phức tạp
Tốt nhất O(NlogN)
xấu nhất N2
Trung bình O(NlogN)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 158


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp vun đống


(Heap Sort)
➔ SV tự tìm hiểu

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 159


Khoa Hệ Thống Thông Tin Quản lý

Giải thuật sắp xếp trộn


(Merge Sort)
➔ SV tự tìm hiểu

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 160


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)

❖Tư tưởng giải thuật


✓ Giải thuật Merge Sort cho Danh sách cần sắp xếp thành 2
Danh sách con..
✓ Nếu Danh sách con thứ 1 có nhiều hơn 1 phần tử thì sắp
xếp Danh sách con này bằng thuật toán Merge Sort
✓ Nếu Danh sách con thứ 2 có nhiều hơn 1 phần tử thì sắp
xếp Danh sách con này bằng thuật toán Merge Sort
✓ Trộn 2 Danh sách con đã được sắp xếp lại với nhau

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 161


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)

❖Ví dụ 1

Nguồn : wikipedia
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 162
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort) ❖Ví dụ 2


❑ Giả sử có hai danh sách đã được sắp xếp a[1..m] và b[1..n]. Ta có thể
trộn chúng lại thành một danh sách mới c[1..m+n] được sắp xếp
theo cách sau:
✓ So sánh hai phần tử đứng đầu của hai danh sách, lấy phần tử nhỏ
hơn cho vào danh sách mới. Tiếp tục như vậy cho tới khi một trong
hai danh sách là rỗng.
✓ Khi một trong hai danh sách là rỗng ta lấy phần còn lại của danh
sách kia cho vào cuối danh sách mới.
Ví dụ ta có a=(1,3,7,9), b=(2,6), quá trình hòa nhập diễn ra như sau:
Danh sách a Danh sách b So sánh Danh sách c
1,3,7,9 2,6 1<2 1
3,7,9 2,6 2<3 1,2
3,7,9 6 3<6 1,2,3
7,9 6 6<7 1,2,3,6
7,9 Nguồn : wikipedia 1,2,3,6,7,9
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 163
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)

int[] M = { 100, 3, 60, 35, 2 };


MergeSort(M,0, n-1);

void MergeSort(int M[],int left,int right)


{
if (left >= right) return;
int mid = (left + right) / 2;
MergeSort(M, left, mid);
MergeSort(M, mid + 1, right);
Merge(M, left, mid, right);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 164


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void Merge(int M[],int left,int mid,int right)
{
int *Temp;
Temp = new int[right - left + 1];
int pos = 0;
int i = left;
int j = mid + 1;
int len;
while(!(i>mid && j>right))
{
if((i<=mid && j <=right && M[i]<M[j]) || j>right)
Temp[pos++] = M[i++];
else
Temp[pos++] = M[j++]; }
len=right-left+1;
for(i=0;i<len;i++)
M[left + i] = Temp[i];
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 165
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) M = { 100, 3, 60, 35, 2 }
{
MergeSort(M,0, M.Length-1)
1 if (left >= right) return;
2 int mid = (left + right) / 2; MergeSort(M,0, 4)
3 MergeSort(M, left, mid);
4 MergeSort(M, mid + 1, right); Left=0, right=4
5 Merge(M, left, mid, right); Mid=(left+right)/2=2
}
void Merge(int M[],int left,int mid,int right) Gọi đệ qui - lần 1:
{
int *Temp; MergeSort(M,left, mid)
Temp = new int[right - left + 1]; Left=0,
int pos = 0; MergeSort(M,0, 2) right=4,
int i = left;
int j = mid + 1; ➔Lưu Stack dòng 4 mid=2
int len;
while(!(i>mid && j>right)) Left=0, right=2
{
if((i<=mid && j <=right && M[i]<M[j]) ||
Mid=(left+right)/2=1 Left=0,
j>right)
Temp[pos++] = M[i++];
Gọi đệ qui - lần 2: right=2,
else mid=1
Temp[pos++] = M[j++]; } MergeSort(M,left, mid);
len=right-left+1; Left=0,
for(i=0;i<len;i++) MergeSort(M,0, 1); right=4,
M[left + i] = Temp[i];
} ➔Lưu Stack dòng 4 mid=2
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 166
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort) Left=0,


void MergeSort(int []M,int left,int right)
right=1,
Left=0, right=1 mid=0
{
1 if (left >= right) return; Mid=(left+right)/2=0 Left=0,
2 int mid = (left + right) / 2; Gọi đệ qui - lần 3: right=2,
3 MergeSort(M, left, mid); mid=1
4 MergeSort(M, mid + 1, right); MergeSort(M,left, mid)
5 Merge(M, left, mid, right);
Left=0,
} MergeSort(M,0, 0) right=4,
void Merge(int M[],int left,int mid,int right)
{
➔Lưu Stack dòng 4 mid=2
int *Temp;
Temp = new int[right - left + 1];
Left=0, right=0
int pos = 0;
int i = left;
➔if: 0>=0➔kết thúc đệ qui
int j = mid + 1; ➔tiến hành gọi Stack
int len;
while(!(i>mid && j>right))
{ Gọi Stack dòng 4- lần 1: Left=0,
if((i<=mid && j <=right && M[i]<M[j]) ||
j>right)
Temp[pos++] = M[i++];
right=2,
else
MergeSort(M,mid+1,right) mid=1
Temp[pos++] = M[j++]; }
len=right-left+1; MergeSort(M,1,1) Left=0,
for(i=0;i<len;i++) right=4,
M[left + i] = Temp[i];
} mid=2
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 167
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort) Left=0,


right=1,
void MergeSort(int []M,int left,int right) ➔Lưu Stack dòng 5 mid=0
{
1 if (left >= right) return; Left=1, right=1 Left=0,
2 int mid = (left + right) / 2;
3 MergeSort(M, left, mid);
➔if: 1>=1➔kết thúc right=2,
đệ qui ➔tiến hành mid=1
4 MergeSort(M, mid + 1, right);
5 Merge(M, left, mid, right);
Left=0,
gọi Stack right=4,
}
void Merge(int M[],int left,int mid,int right) mid=2
{
int *Temp; Gọi Stack dòng 5- lần 1:
Temp = new int[right - left + 1];
int pos = 0; Merge(M,left,mid,right)
int i = left;
int j = mid + 1;
int len;
Merge(M,0,0,1)
while(!(i>mid && j>right))
{
left=0, mid=0,right=1 Left=0,
if((i<=mid && j <=right && M[i]<M[j]) ||
Temp=new int[2] right=2,
j>right)
Temp[pos++] = M[i++]; pos=0 mid=1
else Left=0,
Temp[pos++] = M[j++]; } i=left=0, j=mid+1=1 right=4,
len=right-left+1;
for(i=0;i<len;i++) mid=2
M[left + i] = Temp[i];
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 168
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(0>0 && 1>1)➔đúng
{ Left=0,
1 if (left >= right) return;
if:(0<=0 && 1<=1 &&
2 int mid = (left + right) / 2; M[0]<M[1])||1>1 right=2,
3 MergeSort(M, left, mid); mid=1
if:(0<=0 && 1<=1 &&
4 MergeSort(M, mid + 1, right); Left=0,
5 Merge(M, left, mid, right); 100<3)||1>1➔Sai,else: right=4,
} Temp[pos++] = M[j++]
void Merge(int M[],int left,int mid,int right)
mid=2
{
int *Temp;
Temp[0] = M[1]=3
Temp = new int[right - left + 1]; Pos=1, j=2
int pos = 0;
int i = left; While:!(0>0 && 2>1)➔đúng
int j = mid + 1;
int len; if:(0<=0 && 2<=1 &&
while(!(i>mid && j>right))
{
M[0]<M[2])||2>1
j>right)
if((i<=mid && j <=right && M[i]<M[j]) || if:(0<=0 && 2<=1 &&
Temp[pos++] = M[i++]; 100<60)||2>1➔đúng:
else
Temp[pos++] = M[j++]; } Temp[pos++] = M[i++]
len=right-left+1;
for(i=0;i<len;i++) Temp[1] = M[0]=100
M[left + i] = Temp[i];
} Pos=2, i=1
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 169
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(1>0 && 2>1)➔sai
{ ➔kết thúc while Left=0,
1 if (left >= right) return;
2 int mid = (left + right) / 2; For:-chiều dài Temp=2, right=2,
3 MergeSort(M, left, mid); mid=1
nên lặp 2 lần:
4 MergeSort(M, mid + 1, right); Left=0,
5 Merge(M, left, mid, right);
-khi i=0: M[left+i]=Temp[i]
right=4,
} M[0]=Temp[0]=3 mid=2
void Merge(int M[],int left,int mid,int right)
{ -Khi i=1: M[left+i]=Temp[i]
int *Temp; M[1]=Temp[1]=100
Temp = new int[right - left + 1];
int pos = 0; Ta có mảng mới:
int i = left;
int j = mid + 1; M = { 3, 100, 60, 35, 2 }
int len;
while(!(i>mid && j>right)) Gọi Stack dòng 4- lần 2:
{
if((i<=mid && j <=right && M[i]<M[j]) || MergeSort(M, mid + 1, right);
j>right)
Temp[pos++] = M[i++];
else
Temp[pos++] = M[j++]; }
MergeSort(M, 2, 2);
len=right-left+1; Left=0,
for(i=0;i<len;i++) right=4,
M[left + i] = Temp[i];
} mid=2
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 170
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


Left=0,
void MergeSort(int []M,int left,int right) ➔Lưu Stack dòng 5 right=2,
{ mid=1
1 if (left >= right) return; Left=2, right=2 Left=0,
2 int mid = (left + right) / 2;
3 MergeSort(M, left, mid);
➔if: 2>=2➔kết thúc right=4,
4 MergeSort(M, mid + 1, right); đệ qui mid=2
}
5 Merge(M, left, mid, right); ➔tiến hành gọi Stack
void Merge(int M[],int left,int mid,int right) Gọi Stack dòng 5- lần 2:
{
int *Temp;
Temp = new int[right - left + 1];
Merge(M,left,mid,right)
int pos = 0;
int i = left; Merge(M,0,1,2)
int j = mid + 1;
int len; left=0, mid=1,right=2
while(!(i>mid && j>right))
{ Temp=new int[3] Left=0,
if((i<=mid && j <=right && M[i]<M[j]) ||
j>right) pos=0 right=4,
Temp[pos++] = M[i++];
mid=2
else
Temp[pos++] = M[j++]; }
i=left=0, j=mid+1=2
len=right-left+1;
for(i=0;i<len;i++)
M[left + i] = Temp[i];
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 171
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(0>1 && 2>2)➔đúng
{
1 if (left >= right) return;
if:(0<=1 && 2<=2 &&
M[0]<M[2])||2>2 Left=0,
2 int mid = (left + right) / 2;
3 MergeSort(M, left, mid); right=4,
if:(0<=1 && 2<=2 && mid=2
4 MergeSort(M, mid + 1, right);
5 Merge(M, left, mid, right); 3<60)||2>2➔đúng:
} Temp[pos++] = M[i++]
void Merge(int M[],int left,int mid,int right)
{
int *Temp;
Temp[0] = M[0]=3
Temp = new int[right - left + 1]; Pos=1, i=1
int pos = 0;
int i = left; While:!(1>1 && 2>2)➔đúng
int j = mid + 1;
int len; if:(1<=1 && 2<=2 &&
while(!(i>mid && j>right))
{
M[1]<M[2])||2>2
j>right)
if((i<=mid && j <=right && M[i]<M[j]) || if:(1<=1 && 2<=2 &&
Temp[pos++] = M[i++]; 100<60)||2>2➔sai, else:
else
Temp[pos++] = M[j++]; } Temp[pos++] = M[j++]
len=right-left+1;
for(i=0;i<len;i++) Temp[1] = M[2]=60
M[left + i] = Temp[i];
} Pos=2, j=3
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 172
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(1>1 && 3>2)➔đúng
{ if:(1<=1 && 3<=2 &&
1 if (left >= right) return; M[1]<M[3])||3>2 Left=0,
2 int mid = (left + right) / 2;
3 MergeSort(M, left, mid); if:(1<=1 && 3<=2 && right=4,
4 MergeSort(M, mid + 1, right); 100<35)||3>2➔đúng: mid=2
5 Merge(M, left, mid, right);
} Temp[pos++] = M[i++]
void Merge(int M[],int left,int mid,int right) Temp[2] = M[1]=100
{
int *Temp; Pos=3, i=2
Temp = new int[right - left + 1]; While:!(2>1 && 3>2)➔sai,dừng while
int pos = 0;
int i = left; For:-chiều dài của Temp = 3:
int j = mid + 1;
int len; -khi i=0: M[left+i]=Temp[i]
while(!(i>mid && j>right)) M[0]=Temp[0]=3
{
if((i<=mid && j <=right && M[i]<M[j]) || -Khi i=1: M[left+i]=Temp[i]
j>right) M[1]=Temp[1]=60
Temp[pos++] = M[i++];
else -Khi i=2: M[left+i]=Temp[i]
Temp[pos++] = M[j++]; }
len=right-left+1;
M[2]=Temp[2]=100
for(i=0;i<len;i++) Ta có mảng mới:
M[left + i] = Temp[i];
} M = { 3, 60, 100, 35, 2 }
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 173
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) Gọi Stack dòng 4- lần 3:
{
1 if (left >= right) return;
MergeSort(M, mid + 1, right);
2 int mid = (left + right) / 2;
3 MergeSort(M, left, mid);
MergeSort(M, 3, 4);
4 MergeSort(M, mid + 1, right); ➔Lưu Stack dòng 5 Left=0,
5 Merge(M, left, mid, right);
} Left=3, right=4 right=4,
void Merge(int M[],int left,int mid,int right) mid=2
{ Mid=(left+right)/2=3
int *Temp;
Temp = new int[right - left + 1]; Gọi đệ qui - lần 4:
int pos = 0;
int i = left; MergeSort(M,left, mid);
int j = mid + 1;
Left=3,
int len; MergeSort(M,3, 3);
while(!(i>mid && j>right)) right=4,
{ ➔Lưu Stack dòng 4 mid=3
if((i<=mid && j <=right && M[i]<M[j]) ||
j>right) Left=3, right=3 Left=0,
Temp[pos++] = M[i++];
else ➔if: 3>=3➔kết thúc right=4,
Temp[pos++] = M[j++]; } mid=2
len=right-left+1; đệ qui
for(i=0;i<len;i++)
M[left + i] = Temp[i]; ➔tiến hành gọi Stack
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 174
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort) Left=0,


right=4,
void MergeSort(int []M,int left,int right) Gọi Stack dòng 4- lần 4: mid=2
{
1 if (left >= right) return;
MergeSort(M, mid + 1, right);
2 int mid = (left + right) / 2; MergeSort(M, 4, 4);
3 MergeSort(M, left, mid); Left=3,
4 MergeSort(M, mid + 1, right); ➔Lưu Stack dòng 5 right=4,
5 Merge(M, left, mid, right);
} Left=4, right=4 mid=3
void Merge(int M[],int left,int mid,int right)
{
➔if: 4>=4➔kết thúc Left=0,
int *Temp; đệ qui right=4,
Temp = new int[right - left + 1]; mid=2
int pos = 0; ➔tiến hành gọi Stack
int i = left;
int j = mid + 1; Gọi Stack dòng 5- lần 3:
int len;
while(!(i>mid && j>right)) Merge(M,left,mid,right)
{
if((i<=mid && j <=right && M[i]<M[j]) || Merge(M,3,3,4)
j>right)
Temp[pos++] = M[i++]; left=3, mid=3,right=4
else
Temp[pos++] = M[j++]; } Temp=new int[2] Left=0,
len=right-left+1;
for(i=0;i<len;i++)
pos=0 right=4,
M[left + i] = Temp[i];
i=left=3, j=mid+1=4 mid=2
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 175
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(3>3 && 4>4)➔đúng
{ Left=0,
if:(3<=3 && 4<=4 &&
1 if (left >= right) return;
2 int mid = (left + right) / 2; M[3]<M[4])||4>4 right=4,
3 MergeSort(M, left, mid); if:(3<=3 && 4<=4 && mid=2
4 MergeSort(M, mid + 1, right);
5 Merge(M, left, mid, right);
35<2)||4>4➔sai, else:
} Temp[pos++] = M[j++]
void Merge(int M[],int left,int mid,int right)
{ Temp[0] = M[4]=2
int *Temp;
Temp = new int[right - left + 1]; Pos=1, j=5
int pos = 0;
int i = left; While:!(3>3 && 5>4)➔đúng
int j = mid + 1;
int len;
if:(3<=3 && 5<=4 &&
while(!(i>mid && j>right)) M[3]<M[5])||5>4➔đúng:
{
if((i<=mid && j <=right && M[i]<M[j]) || Temp[pos++] = M[i++]
j>right)
Temp[pos++] = M[i++];
else Temp[1] = M[3]=35
Temp[pos++] = M[j++]; } Pos=2, i=4
len=right-left+1;
for(i=0;i<len;i++) While:!(4>3 && 5>4)➔sai, dừng
M[left + i] = Temp[i];
} while
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 176
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) For:-chiều dài của Temp = 2:
{ -khi i=0: M[left+i]=Temp[i]
1 if (left >= right) return;
2 int mid = (left + right) / 2;
M[3]=Temp[0]=2
3 MergeSort(M, left, mid); -Khi i=1: M[left+i]=Temp[i] Left=0,
4 MergeSort(M, mid + 1, right); M[4]=Temp[1]=35 right=4,
5 Merge(M, left, mid, right); mid=2
} Ta có mảng mới:
void Merge(int M[],int left,int mid,int right) M = { 3, 60, 100, 2, 35 }
{
int *Temp;
Temp = new int[right - left + 1]; Gọi Stack dòng 5- lần 4:
int pos = 0;
int i = left; Merge(M,left,mid,right)
int j = mid + 1;
int len; Merge(M,0,2,4)
while(!(i>mid && j>right))
{ left=0, mid=2,right=4
if((i<=mid && j <=right && M[i]<M[j]) ||
j>right) Temp=new int[5]
Temp[pos++] = M[i++];
else
pos=0
Temp[pos++] = M[j++]; }
len=right-left+1;
i=left=0, j=mid+1=3
for(i=0;i<len;i++)
M[left + i] = Temp[i];
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 177
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(0>2 && 3>4)➔đúng
{
if:(0<=2 && 3<=4 &&
1 if (left >= right) return;
2 int mid = (left + right) / 2; M[0]<M[3])||3>4
3 MergeSort(M, left, mid); if:(0<=2 && 3<=4 &&
4 MergeSort(M, mid + 1, right);
5 Merge(M, left, mid, right);
3<2)||3>4➔sai, else:
} Temp[pos++] = M[j++]
void Merge(int M[],int left,int mid,int right)
{ Temp[0] = M[3]=2
int *Temp;
Temp = new int[right - left + 1]; Pos=1, j=4
int pos = 0;
int i = left;
While:!(0>2 && 4>4)➔đúng
int j = mid + 1; if:(0<=2 && 4<=4 &&
int len;
while(!(i>mid && j>right)) M[0]<M[4])||4>4
{
if((i<=mid && j <=right && M[i]<M[j]) || if:(0<=2 && 4<=4 &&
j>right)
Temp[pos++] = M[i++];
3<35)||4>4➔đúng:
else
Temp[pos++] = M[j++]; }
Temp[pos++] = M[i++]
len=right-left+1;
for(i=0;i<len;i++) Temp[1] = M[0]=3
}
M[left + i] = Temp[i]; Pos=2, i=1
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 178
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(1>2 && 4>4)➔đúng
{ if:(1<=2 && 4<=4 &&
1 if (left >= right) return;
2 int mid = (left + right) / 2;
M[1]<M[4])||4>4
3 MergeSort(M, left, mid); if:(0<=2 && 4<=4 &&
4 MergeSort(M, mid + 1, right);
5 Merge(M, left, mid, right);
60<35)||4>4➔sai, else:
}
void Merge(int M[],int left,int mid,int right) Temp[pos++] = M[j++]
{
int *Temp; Temp[2] = M[4]=35
Temp = new int[right - left + 1];
int pos = 0;
Pos=3, j=5
int i = left;
int j = mid + 1; While:!(1>2 && 5>4)➔đúng
int len;
while(!(i>mid && j>right))
if:(1<=2 && 5<=4 &&
{ M[1]<M[5])||5>4➔đúng:
if((i<=mid && j <=right && M[i]<M[j]) ||
j>right)
Temp[pos++] = M[i++]; Temp[pos++] = M[i++]
else
Temp[pos++] = M[j++]; } Temp[3] = M[1]=60
len=right-left+1;
for(i=0;i<len;i++) Pos=4, i=2
M[left + i] = Temp[i];
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 179
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


void MergeSort(int []M,int left,int right) While:!(2>2 && 5>4)➔đúng
{ if:(2<=2 && 5<=4 &&
1 if (left >= right) return;
2 int mid = (left + right) / 2; M[2]<M[5])||5>4➔đúng:
3 MergeSort(M, left, mid); Temp[pos++] = M[i++]
4 MergeSort(M, mid + 1, right);
5 Merge(M, left, mid, right); Temp[4] = M[2]=100
} Pos=5, i=3
void Merge(int M[],int left,int mid,int right)
{ While:!(3>2 && 5>4)➔sai, dừng
int *Temp;
Temp = new int[right - left + 1]; while
int pos = 0; For:-chiều dài của Temp = 5:
int i = left;
int j = mid + 1; -i=0: M[left+i]=Temp[i]M[0]=Temp[0]=2
int len; -i=1: M[left+i]=Temp[i]M[1]=Temp[1]=3
while(!(i>mid && j>right))
{ -i=2: M[left+i]=Temp[i]M[2]=Temp[2]=35
if((i<=mid && j <=right && M[i]<M[j]) ||
j>right)
-i=3: M[left+i]=Temp[i]M[3]=Temp[3]=60
Temp[pos++] = M[i++]; -i=4: M[left+i]=Temp[i]M[4]=Temp[4]=100
else
Temp[pos++] = M[j++]; } Kiểm tra Stack rỗng, kết thúc
len=right-left+1;
for(i=0;i<len;i++)
giải thuật➔ta có mảng sắp xếp:
M[left + i] = Temp[i]; M = { 2, 3, 35, 60, 100 }
}
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 180
Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)


❑ Quan sát ta thấy quá trình trộn cho danh sách diễn ra như sau:

100 3 60 35 2
1
3 100 60 35 2
2 3 60 100 35 2
3 3 60 100 2 35
4 2 3 35 60 100

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 181


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)

Bài tập 1: Hãy giải thích từng bước quá trình chạy
Merge Sort cho danh sách dưới đây:
int[] M = {10,15,2,8,7};
MergeSort(M,0,n-1);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 182


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)

Bài tập 2: Cho danh sách Sinh viên, mỗi Sinh viên có
các thông số: Mã(int), tên(chuỗi), ngày sinh
(DateTime)
- Hãy xây dựng cấu trúc dữ liệu cho mô tả trên
- Hãy viết giải thuật Merge Sort để: Sắp xếp theo tên
tăng dần, nếu tên trùng nhau thì sắp xếp theo
ngày sinh giảm dần.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 183


Khoa Hệ Thống Thông Tin Quản lý

Phương pháp sắp xếp trộn (Merge Sort)

❑ Ðánh giá giải thuật


• Chi phí thực hiện của giải thuật MergeSort sẽ là O(nlog2n).
Do không sử dụng thông tin nào về đặc tính của dãy cần sắp
xếp, nên trong mọi trường hợp của thuật toán chi phí là
không đổi. Ðây cũng chính là một trong những nhược điểm
lớn của thuật toán

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 184


Khoa Hệ Thống Thông Tin Quản lý

So sánh độ phức tạp các giải thuật

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 185


TRƯỜNG ĐẠI HỌC NGÂN HÀNG TP HCM
KHOA HỆ THỐNG THÔNG TIN QUẢN LÝ

Chương 7

Tìm kiếm
1
Khoa Hệ Thống Thông Tin Quản lý

Nội dung

❖Khái niệm và vai trò của việc tìm kiếm dữ liệu


❖Một số giải thuật tìm kiếm phổ biến
✓ Tìm kiếm Tuyến Tính
✓ Tìm kiếm Nhị Phân
❖Minh họa thuật toán
❖Đánh giá độ phức tạp của thuật toán

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 2


Khoa Hệ Thống Thông Tin Quản lý

Đặt vấn đề

Minion
răng sún
đâu rồi nhỉ

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 3


Khoa Hệ Thống Thông Tin Quản lý

Đặt vấn đề
Oh My God!
Đồ đạc tùm lum
thế này làm sao
tìm thấy chìa khóa

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 4


Khoa Hệ Thống Thông Tin Quản lý

Đặt vấn đề
Số 6 ở
đâu nhỉ?

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 5


Khoa Hệ Thống Thông Tin Quản lý

Khái niệm

✓Tìm kiếm là việc ta muốn lọc ra một hay một


số đối tượng (phần tử) “có những đặc tính
nào đó” từ một tập dữ liệu có trước để xử lý.
Dữ liệu bên trong để Tìm kiếm
không theo thứ tự tuần tự

Tập dữ liệu Tìm kiếm


có trước tuần tự
Dữ liệu bên trong để
có theo thứ tự
Tìm kiếm
Nhị phân

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 6


Khoa Hệ Thống Thông Tin Quản lý

Một số giải thuật Tìm kiếm phổ biến

✓Đơn giản hóa bài toán:


Để đơn giản hoá bài toán và cho việc biểu diễn
thuật toán dễ dàng mà không làm mất tính tổng
quát, xem như:
* Dữ liệu cho tìm kiếm là một mảng các số nguyên
* Dữ liệu tìm kiếm : (khoá) giá trị số nguyên
M[0] M[1] M[2] M[…] M[N-2] M[N-1]

15 22 9 … 100 30

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 7


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Xét phần tử từ đầu cho đến cuối một cách tuần tự


Tại vị trí thứ i:
Nếu giá trị trong dữ liệu đúng với khoá cần tìm kiếm
-> tìm thấy
Nếu không đúng tìm đến phần tử kế tiếp i+1
Nếu sau khi xét hết N phần tử mà không có giá trị
khoá cần tìm → không tìm thấy

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 8


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Mã giả:
➢ Bước 1: i = 0 ➔ bắt đầu từ phần tử đầu tiên của dãy
➢ Bước 2: So sánh M[i] với x, có 2 khả năng :
+ M[i] = x : Tìm thấy. Dừng
+ M[i] ≠ x : Sang Bước 3.
➢ Bước 3 : i = i+1➔ xét tiếp phần tử kế trong mảng
Nếu i >=N: Hết mảng, không tìm thấy. Dừng
Ngược lại: Lặp lại Bước 2.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 9


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Cài đặt giải thuật:

for (i=0;i<N;i++)
{
if(M[i]==x)
printf (“tìm thấy tại vị trí %d”,i);
}
if (i>=N)
printf (“không tìm thấy”);
(với x là biến khoá nhập vào cho tìm kiếm )

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 10


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

➢ Ví dụ: Cho dãy số M


25 20 9 5 7 4 13 17
➢ Giá trị cần tìm: x= 9

i=0
X=9

25 20 9 5 7 4 13 17

0 1 2 3 4 5 6 7

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 11


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

i=1
X=9

25 20 9 5 7 4 13 17

0 1 2 3 4 5 6 7

i=2
X=9

25 20 9 5 7 4 13 17

0 1 2 3 4 5 6 7

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 12


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Int M[] = { 25,20,9,5,7,4,13,17 };

int LinearSearch(int M,int x, int n)


{
int i;
for (i = 0; (i < n) && (M[i] != x); i++);
if (i == n)
return -1;// tìm hết mảng nhưng không có x
else
return i; // M[i] là phần tử có khoá x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 13


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Int M[]= { 25,20,9,5,7,4,13,17 };

int LinearSearch(int M[], int x, int n)


{
int i;
for (i = 0; i < n; i++)
{
if(M[i] == x)
return i; // M[i] là phần tử có khoá x
}
return -1;// tìm hết mảng nhưng không có x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 14


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Int M[] = { 25,20,9,5,7,4,13,17 };

int LinearSearch(int M, int x, int n)


{
int tam = -1;
for (int i = 0; i < n; i++)
{
if(M[i] == x) tam = i; // M[i] là phần tử có khoá x
}
return tam;//tam=-1 nếu tìm hết mảng nhưng không có x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 15


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Cải tiến cài đặt: dùng phương pháp “lính canh”


• Đặt thêm một phần tử có giá trị x vào cuối mảng
• Bảo đảm luôn tìm thấy x trong mảng
• Sau đó dựa vào vị trí tìm thấy để kết luận.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 16


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính


int LinearSearch(int x){
// mảng gồm N phần tử từ M[0]..M[N-1]
M[N] = x; // thêm phần tử thứ N+1
for ( i=0; (M[i]!=x );i++);
if (i==N)
return -1; // tìm hết mảng nhưng không có x
else
return i; // tìm thấy x tại vị trí i
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 17


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

Ðánh giá giải thuật


Trường hợp Số lần so Giải thích
sánh
Tốt nhất 1 Phần tử đầu tiên có giá trị k
Xấu nhất n+1 Phần tử cuối cùng có giá trị k
Trung bình (n+1)/2 Giả sử xác suất các phần tử trong
mảng nhận giá trị x là như nhau.

Vậy giải thuật tìm tuyến tính có độ phức tạp tính toán
cấp n: T(N) = O(N)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 18


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

➢ Nhận xét:
✓ Giải thuật tìm tuyến tính không phụ thuộc vào thứ tự
của các phần tử mảng, do vậy đây là phương pháp
tổng quát nhất để tìm kiếm trên một dãy bất kỳ.
✓ Một Giải thuật có thể được cài đặt theo nhiều cách
khác nhau, kỹ thuật cài đặt ảnh hưởng đến tốc độ
thực hiện của giải thuật.

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 19


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

❖ Cải tiến giải thuật


Giải Thuật tìm kiếm tuyến tính cải tiến:
Chỉ xét tìm kiếm giá trị x đến phần tử thứ m trong dữ
liệu với x còn nhỏ hơn Mm
while ((x<=M[i])&&(i<=N) i++;
if(M[i]==x) printf(“tìm thấy tại %d”,i);
else printf(‘không tìm thấy ’);
(với x là biến khoá nhập vào cho tìm kiếm )

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 20


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Tuyến Tính

❖ Bài tập: Cho danh sách sản phẩm gồm các thông
tin: Mã, tên, đơn giá. Hãy mô hình hóa dữ liệu và
viết các giải thuật tìm kiếm Tuần tự:
✓ Tìm sản phẩm có mã X
✓ Tìm các sản phẩm có đơn giá [A…B]
✓ Tìm các sản phẩm mà phần tên có chứa Z

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 21


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Đặc trưng Dữ liệu: Đã được sắp xếp theo một thứ tự
nào đó (nhỏ→ lớn)
❖ Tính chất của dữ liệu được sắp là :
Mi-1<= Mi<=Mi+1
➔Vậy nếu x> Mi thì x chỉ có thể xuất hiện trong đoạn
[Mi+1 ,MN-1] của dãy, ngược lại nếu x< Mi thì x chỉ có
thể xuất hiện trong đoạn [M0 ,Mi-1] của dãy
❖ Giải thuật tìm nhị phân áp dụng nhận xét trên đây với
tư tưởng chia để trị để tìm cách giới hạn phạm vi tìm
kiếm sau mỗi lần so sánh x với một phần tử trong dãy.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 22
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân

Mi-1 Mi Mi+1

Mi>x Mi<x

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 23


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Cài đặt giải thuật:
Bước 1: left = 0; right = N-1; // tìm kiế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 M[mid] với k, có 3 khả năng :
M[mid] = k: Tìm thấy. Dừng
M[mid] > k: Tìm tiếp x trong dãy con M[left] .. M[mid -1] :
right =mid - 1;
M[mid] < k: Tìm tiếp x trong dãy con M[mid +1] .. M[right] :
left = mid + 1;
Bước 3:
Nếu left <= right : Còn phần tử chưa xét → tìm tiếp.
Lặp lại Bước 2.
Ngược lại: Dừng; //Ðã xét hết tất cả các phần tử, không tìm thấy.
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 24
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Cài đặt giải thuật:
int BinarySearch(int M[],int n, int x)
{
int left = 0, right = n-1;
int mid;
do
{
mid = (left + right) / 2;
if (x == M[mid])
return mid;//Thấy x tại mid
else if (x < M[mid])
right = mid - 1;
else
left = mid + 1;
} while (left <= right);
return -1; // Tìm hết dãy mà không có x
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 25


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1

int M[] = {1, 5, 15, 19, 25, 27, 29, 31,33,45,55,88,100};

int kq= BinarySearch(M,13, 19);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 26


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1


M
Tìm phần tử X = 19
0 1
1 5
2 15
3 19
4 25
5 27
Middle=(0+12)/2=6
6 29
M[6]=29 > x= 19
7 31
➔Ta tìm phần nửa nhỏ hơn còn lại của M
8 33
(tức là từ 0→5)
9 45
10 55
11 88
12 100
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 27
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1


M
Tìm phần tử X = 19
0 1
1 5
2 15 Middle=(0+5)/2=2
3 19 M[2]=15 < x= 19
4 25
5 27 ➔Ta tìm phần nửa lớn hơn còn lại của M
(tức là từ 3→5)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 28


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1

Tìm phần tử X = 19
M

3 19
Middle=(3+5)/2=4
4 25 M[4]=25 > x= 19
5 27
➔Ta tìm phần nửa nhỏ hơn còn lại của M
(tức là từ 3→3)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 29


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 1

Tìm phần tử X = 19
M

19 Middle=(3+3)/2=3
3
M[3]=19 = x =19
Tìm thấy X=19 ở vị trí thứ 3

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 30


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2

int[] M = { 1, 5, 15, 19, 25, 27, 29, 31,33,45,55,88,100};

int kq= BinarySearch(M,13, 18);

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 31


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2


M
Tìm X = 18
0 1
1 5
2 15
3 19
4 25
5 27
6 29 Middle=(0+12)/2=6
7 31 M[6]=29 > x= 18
8 33 ➔Ta tìm phần nửa nhỏ hơn còn lại của M
9 45 (tức là từ 0→5)
10 55
11 88
12 100
GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 32
Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2


M
Tìm X = 18
0 1
1 5
2 15 Middle=(0+5)/2=2
3 19 M[2]=15 < x= 18
4 ➔Ta tìm phần nửa lớn hơn còn lại của M
25
5 (tức là từ 3→5)
27

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 33


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2

Tìm X = 18
M

3 19
4 Middle=(3+5)/2=4
25
5 M[4]=25 > x= 18
27
➔Ta tìm phần nửa nhỏ hơn còn lại của M
(tức là từ 3→3)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 34


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 2

Tìm X = 18
M

3 19 Middle=(3+3)/2=3
M[3]=19 > x= 18
➔không còn phần tử nào để so sánh.

Không tim thấy x=18

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 35


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân ❖ Ví dụ minh họa 3

int[] M = { 18, 5, 25, 10, 22, 3, 29};

int kq=BinarySearch(M,7 25);


Nhận xét dữ liệu có vấn đề gì không?

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 36


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Đánh giá giải thuật
Trường Số lần Giải thích
hợp so sánh
Tốt nhất 1 Phần tử giữa của mảng có giá trị x
Xấu nhất log 2 n Không có x trong mảng
Trung bình log 2 n/2 Giả sử xác suất các phần tử trong
mảng nhận giá trị x là như nhau

Vậy giải thuật tìm Nhị Phân có độ phức tạp tính toán cấp n:
T(N) = O(log 2 N)

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 37


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Nhận xét
➢ Giải thuật tìm nhị phân dựa vào quan hệ giá trị của
các phần tử mảng để định hướng trong quá trình tìm
kiếm, do vậy chỉ áp dụng được cho những dãy đã có
thứ tự.
➢ Giải thuật tìm nhị phân tiết kiệm thời gian hơn rất
nhiều so với giải thuật tìm tuyến tính do
➢ Tnhị phân (N) = O(log 2 N) < Ttuyến tính (N) = O(N).

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 38


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Nhận xét
➢ Khi muốn áp dụng giải thuật tìm nhị phân cần phải xét
đến thời gian sắp xếp dãy số để thỏa điều kiện dãy số có
thứ tự. Thời gian này không nhỏ, và khi dãy số biến động
cần phải tiến hành sắp xếp lại => khuyết điểm chính cho
giải thuật tìm nhị phân.
➢ Cần cân nhắc nhu cầu thực tế để chọn một trong hai giải
thuật tìm kiếm trên sao cho có lợi nhất
➢ Thường xuyên biến động, ít tìm kiếm → tuần tuyến tính
➢ Ít biến động, tần suất tìm kiếm nhiều → nhị phân

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 39


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân


❖ Mở rộng: Cài đặt bằng Đệ qui
➢ Phát hiện: Phần cơ sở khi left>Right hoặc tìm thấy,
phần đệ qui là lặp lại quá trình chia danh sách

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 40


Khoa Hệ Thống Thông Tin Quản lý

Tìm kiếm Nhị Phân

int[] M = { 1, 5, 15, 19, 25, 27, 29, 31,33,45,55,88,100};

MessageBox.Show("" + BinarySearch(M, 27, 0, M.Length-1));

int BinarySearch(int []M, int x, int left, int right)


{
if (left > right)
return -1;
int mid = (left + right) / 2;
if (x == M[mid])
return mid;
if (x < M[mid])
return BinarySearch(M, x, left, mid - 1);
return BinarySearch(M, x, mid + 1, right);
}

GV: ThS. Nguyễn Văn Thọ - thonv@buh.edu.vn 41

You might also like