B03 - Tìm kiếm

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 34

Chương 3

Tìm kiếm và sắp xếp


Nội dung

3.1 Tìm 3.2 Sắp


kiếm xếp

Cấu trúc dữ liệu - Khoa CNTT 2


3.1 Tìm kiếm
 Tìm kiếm là thao tác quan trọng & thường xuyên
trong tin học.
- Tìm kiếm một nhân viên trong danh sách nhân viên.

- Tìm một sinh viên trong danh sách sinh viên của một
lớp…

- Tìm kiếm một tên sách trong thư viện.

Cấu trúc dữ liệu - Khoa CNTT 4


3.1 Tìm kiếm
 Tìm kiếm là quá trình xác định một đối tượng nào đó
trong một tập các đối tượng. Kết quả trả về là đối
tượng tìm được (nếu có) hoặc một chỉ số (nếu có)
xác định vị trí của đối tượng trong tập đó.
 Việc tìm kiếm dựa theo một trường nào đó của đối
tượng, trường này là khóa (key) của việc tìm kiếm.
 VD: đối tượng sinh viên có các dữ liệu {MaSV,
HoTen, DiaChi,…}. Khi đó tìm kiếm trên danh sách
sinh viên thì khóa thường chọn là MaSV hoặc
HoTen.
Cấu trúc dữ liệu - Khoa CNTT 5
3.1 Tìm kiếm
 Bài toán được mô tả như sau:
- Tập dữ liệu được lưu trữ là dãy a[0], a[1],..,a[n-1].
Giả sử chọn cấu trúc dữ liệu mảng để lưu trữ dãy
số này trong bộ nhớ chính, có khai báo:
const int n=10;
int a[n];
- Khóa cần tìm là x, có kiểu nguyên: int x;
- Tìm xem trong mảng có phần tử nào bằng x không?
- Nếu tìm thấy trả về chỉ số của phần tử đó
- Nếu không tìm thấy trả về -1

Cấu trúc dữ liệu - Khoa CNTT 6


3.1 Tìm kiếm
 Phương pháp tìm kiếm:

Tìm kiếm

Tìm kiếm tuyến tính Tìm kiếm nhị phân

Tập dữ liệu Tập dữ liệu đã


bất kỳ được sắp xếp

Cấu trúc dữ liệu - Khoa CNTT 7


3.1.1 Tìm kiếm tuyến tính
 Ý tưởng chính: duyệt tuần tự từ phần tử đầu tiên,
lần lượt so sánh khóa tìm kiếm với các phần tử
trong mảng. Cho đến khi gặp phần tử cần tìm hoặc
đến khi duyệt hết mảng.

Cấu trúc dữ liệu - Khoa CNTT 8


3.1.1 Tìm kiếm tuyến tính
 Các bước tiến hành:
- Bước 1: duyệt tuần tự từ phần tử đầu tiên;

- Bước 2: so sánh các phần tử trong mảng với khóa tìm


kiếm có hai khả năng:
 Nếu bằng nhau  Tìm thấy  Dừng

 Nếu khác nhau chuyển Sang bước 3

- Bước 3: xét phần tử kế tiếp trong mảng


 Nếu hết mảng, không tìm thấy.  Dừng

 Nếu chưa hết mảng quay lại bước 2

Cấu trúc dữ liệu - Khoa CNTT 9


3.1.1 Tìm kiếm tuyến tính
 Các bước tiến hành:
- Bước 1: i = 0;
- Bước 2: So sánh a[i] với x, có hai khả năng
 a[i] = x: Tìm thấy  Trả về i  Dừng
 a[i]  x: Sang bước 3
- Bước 3: i ++; // xét phần tử kế tiếp trong mảng
 Nếu i > n: Hết mảng, không tìm thấy  Trả về -1 
Dừng
 Nếu i  n: Quay lại bước 2

Cấu trúc dữ liệu - Khoa CNTT 10


3.1.1 Tìm kiếm tuyến tính
 Ví dụ: Cho dãy số a, giá trị tìm x = 8
12 2 5 8 1 6 4

Minh họa tìm kiếm tuyến tính

Tìm thấy

X=8

12 2 5 8 1 6 4

Cấu trúc dữ liệu - Khoa CNTT 11


3.1.1 Tìm kiếm tuyến tính
 Ví dụ: Cho dãy số a, giá trị tìm x = 9
12 2 5 8 1 6 4
Minh họa tìm kiếm tuyến tính

Không
tìm thấy

X=9

12 2 5 8 1 6 4

Cấu trúc dữ liệu - Khoa CNTT 12


3.1.1 Tìm kiếm tuyến tính
 Thuật toán tìm kiếm tuyến tính
1. int LinearSearch(int a[], int n, int x)
2. {
3. int i =0;
4. while (i<n) && (a[i] != x)
5. i++;
6. if (i >= n)
7. return -1; //tìm không thấy
8. else
9. return i; //tìm thấy tại vị trí i
10.}

Cấu trúc dữ liệu - Khoa CNTT 13


3.1.1 Tìm kiếm tuyến tính
 Ví dụ: Cho dãy số a, giá trị tìm x = 9
12 2 5 8 1 6 4
Minh họa tìm kiếm tuyến tính

Không
tìm thấy

X=9

12 2 5 8 1 6 4 9

Cấu trúc dữ liệu - Khoa CNTT 14


3.1.1 Tìm kiếm tuyến tính
 Thuật toán tìm kiếm tuyến tính cải tiến
1. int LinearSearch(int a[], int n, int x)
2. {
3. int i =0;
4. a[n] = x; //thêm phần tử x vào cuối dãy
5. while (a[i] != x)
6. i++;
7. if (i == n)
8. return -1; //không tìm thấy
9. else
10. return i; //tìm thấy x tại vị trí i
11.}

Cấu trúc dữ liệu - Khoa CNTT 15


3.1.1 Tìm kiếm tuyến tính
 Đánh giá giải thuật

 Thời gian thực hiện giải thuật là thời gian thưc hiện câu lệnh
while.
 Thời gian thực hiện câu lệnh while phụ thuộc tình trạng dữ liệu
vào.

Cấu trúc dữ liệu - Khoa CNTT 16


3.1.1 Tìm kiếm tuyến tính

Cấu trúc dữ liệu - Khoa CNTT 17


3.1.1 Tìm kiếm tuyến tính

 Nhận xét
- Giải thuật tìm kiếm tuyến tính không phụ thuộc vào thứ tự của
các phần tử trong 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 thuật toán có thể được cài đặt theo nhiều cách khác nhau,
kỹ thuật cài đặt ảnh hưởng nhiều đến tốc độ thực hiện. Ví dụ
như thuật toán Search cải tiến sẽ chạy nhanh hơn thuật toán
trước do vòng lặp while chỉ so sánh một điều kiện...

Cấu trúc dữ liệu - Khoa CNTT 18


3.1.2 Tìm kiếm nhị phân
Phép tìm kiếm nhị phân được áp dụng trên dãy khóa
đã có thứ tự: a[0]  a[1]  ...  a[n-1].

Cấu trúc dữ liệu - Khoa CNTT 19


3.1.2 Tìm kiếm nhị phân
 Ý tưởng: Ngôn ngữ tự nhiên
- Giả sử ta cần tìm trong đoạn a[left,..,right] với khóa tìm
kiếm là x, trước hết ta xét phần tử giữa là a[mid], với
mid=[left+right]/2.
 Nếu a[mid] = x thì việc tìm kiếm thành công.
 Nếu a[mid] < x thì có nghĩa là đoạn a[left] đến
a[mid] chỉ chứa khóa < x, ta tiến hành tìm kiếm từ
a[mid+1] đến a[right].
 Nếu a[mid] > x thì có nghĩa là đoạn a[mid] đến
a[right] chỉ chứa khoá > x, ta tiến hành tìm kiếm từ
a[left] đến a[mid-1].
- Quá trình tìm kiếm thất bại nếu left > right.

Cấu trúc dữ liệu - Khoa CNTT 20


3.1.2 Tìm kiếm nhị phân
 Các bước tiến hành: Giả ngôn ngữ
- B1: left =0, right = n-1; // tìm kiếm trên tất cả phần tử
- B2: mid = (left + right)/2 // lấy mốc so sánh
So sánh a[mid] với x, có 3 khả năng
 a[mid] = x: Tìm thấy  Trả về mid  Dừng
 a[mid] > x: // tìm tiếp trong dãy a[left]...a[mid-1]
right = mid -1;
 a[mid] < x: // tìm tiếp trong dãy a[mid+1]...a[right]
left = mid +1;
- B3:
 Nếu left  right // còn phần tử  tìm tiếp  Lặp B2
 Ngược lại: Trả về -1  Dừng //đã xét hết các phần tử
Cấu trúc dữ liệu - Khoa CNTT 21
3.1.2 Tìm kiếm nhị phân

Ví dụ: cho dãy số gồm 8 phần tử bên dưới và x = 8:


1 2 4 5 6 8 12 15
X=8

1 2 4 5 6 8 12 15
Left = 0 Mid = 3 Right = 7
Đoạn tìm kiếm

X=8
=

1 2 4 5 6 8 12 15
Left = 4 Mid = 5 Right = 7

Đoạn tìm kiếm

Cấu trúc dữ liệu - Khoa CNTT 22


3.1.2 Tìm kiếm nhị phân

Ví dụ: cho dãy số gồm 8 phần tử bên dưới và x = 7:


1 2 4 5 6 8 12 15
X=7

1 2 4 5 6 8 12 15
Left = 0 Mid = 3 Right = 7
Đoạn tìm kiếm

X=7

1 2 4 5 6 8 12 15
Left = 4 Mid = 5 Right = 7

Đoạn tìm kiếm

Cấu trúc dữ liệu - Khoa CNTT 23


3.1.2 Tìm kiếm nhị phân
 Thuật toán tìm kiếm NP BinarySearch
1. int BinarySearch(int a[], int n,int x)
2. { int left = 0, right = n-1, mid;
3. while (left <= right)
4. { mid = (left + right)/2; //lấy điểm giữa
5. if (a[mid] == x) //tìm thấy
6. return mid;
7. else if (a[mid]<x) //tìm bên phải mid
8. left = mid+1;
9. else //tìm đoạn bên trái mid
10. right = mid-1;
11. }
12. return -1; //không tìm được
13.}
Cấu trúc dữ liệu - Khoa CNTT 24
3.1.2 Tìm kiếm nhị phân

 Nhận xét
- Giải thuật nhị phân dựa vào quan hệ giá trị của các phần tử
trong mảng để định hướng trong quá trình tìm kiếm, do vậy
chỉ áp dụng được với dãy đã có thứ tự.
- Giải thuật nhị phân tìm kiếm nhanh hơn tìm kiếm tuyến tính.
- Tuy nhiên khi áp dụng giải thuật nhị phân thì cần phải quan
tâm đến chi phí cho việc sắp xếp mảng. Vì khi mảng được
sắp thứ tự rồi thì mới tìm kiếm nhị phân.

Cấu trúc dữ liệu - Khoa CNTT 25


Câu hỏi củng cố bài
1. Thời gian tồi tệ nhất cho tìm kiếm tuần tự một phần
tử trong một mảng là gì?

A. O (1)

B. O (nlog2n)

C. O (n)

D. O (n ^ 2)

Cấu trúc dữ liệu - Khoa CNTT 26


Câu hỏi củng cố bài
2.Thời gian tồi tệ nhất cho tìm kiếm nhị phân một phần
tử trong một mảng là gì?

A. O (1)

B. O (log2n)

C. O (n^2)

D. O (n)

Cấu trúc dữ liệu - Khoa CNTT 27


Câu hỏi củng cố bài
3. Cho dãy số sau: 1, 2, 4, 5, 6, 8, 12, 15
Tại thời điểm kết thúc thuật toán tìm kiếm nhị phân
(Binary Search) thì left, right, mid nhận giá trị bao
nhiêu khi giá trị cần tìm là x=8.
A. left=5, right=8, mid=6
B. left=5, right=7, mid=6
C. left=4, right=7, mid=6
D. left=4, right=7, mid=5

Cấu trúc dữ liệu - Khoa CNTT 28


Câu hỏi củng cố bài
4. Cho dãy số sau: 1, 2, 4, 5, 6, 8, 12, 15
Tại thời điểm kết thúc thuật toán tìm kiếm nhị phân
(Binary Search) thì biến right nhận giá trị bao nhiêu tại
thời điểm kết thúc gọi hàm khi giá trị cần tìm là x=7.
A. 6
B. 5
C. 4
D. 3

Cấu trúc dữ liệu - Khoa CNTT 29


Câu hỏi củng cố bài
5. Cho dãy số sau: 1, 2, 4, 5, 6, 8, 12, 15
Tại thời điểm kết thúc thuật toán tìm kiếm nhị phân
(Binary Search) thì biến left nhận giá trị bao nhiêu tại
thời điểm kết thúc gọi hàm khi giá trị cần tìm là x=7.
A. 5
B. 4
C. 3
D. 2

Cấu trúc dữ liệu - Khoa CNTT 30


Tổng kết int LinearSearch(..)
{

}
Giải thuật Tốt nhất: O(1)
Tìm kiếm tuần
tự
Tìm kiếm

Độ phức tạp Trung bình: O(n)

Xấu nhất: O(n)

int BinarySearch(..)
Giải thuật {

Tìm kiếm nhị
}
phân
Độ phức tạp Xấu nhất: O(log2n)

Cấu trúc dữ liệu - Khoa CNTT 31


Bài tập
Bài 1
Minh họa giải thuật tìm kiếm tuần tự để tìm giá trị x =
36 trong dãy khóa sau:
42 23 65 11 87 36 94 50 79

Bài 2
Minh họa giải thuật tìm kiếm tuần tự để tìm giá trị x =
32 trong dãy khóa sau:
42 23 65 11 87 36 94 50 79

Cấu trúc dữ liệu - Khoa CNTT 32


Bài tập
Bài 3
Minh họa giải thuật tìm kiếm nhị phân để tìm giá trị x = 79
trong dãy khóa sau:
11 23 36 42 50 65 68 79 87 94
Bài 4
Minh họa giải thuật tìm kiếm nhị phân để tìm giá trị x = 25
trong dãy khóa sau:
11 23 36 42 50 65 68 79 87 94

Cấu trúc dữ liệu - Khoa CNTT 33


Tài liệu tham khảo
[1]. Giáo trình Cấu trúc dữ liệu và giải thuật – Lê Văn
Vinh, NXB Đại học quốc gia TP HCM, 2013
[2]. Cấu trúc dữ liệu & thuật toán, Đỗ Xuân Lôi, NXB
Đại học quốc gia Hà Nội, 2010.
[3]. Trần Thông Quế, Cấu trúc dữ liệu và thuật toán
(phân tích và cài đặt trên C/C++), NXB Thông tin và
truyền thông, 2018
[4]. Robert Sedgewick, Cẩm nang thuật toán, NXB
Khoa học kỹ thuật, 2004 .
[5]. PGS.TS Hoàng Nghĩa Tý, Cấu trúc dữ liệu và
thuật toán, NXB xây dựng, 2014

Cấu trúc dữ liệu - Khoa CNTT 34


Cấu trúc dữ liệu - Khoa CNTT 35

You might also like