Tải bản đầy đủ (.ppt) (40 trang)

Slide Cấu trúc dữ liệu và giải thuật: Giải thuật tìm kiếm

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.49 MB, 40 trang )

CHƯƠNG II

SEARCHING TECHNIQUES
TÌM KIẾM


2

Nội dung
1.

Khái quát về tìm kiếm

2.

Tìm tuyến tính (Linear Search)

3.

Tìm nhị phân (Binary Search)

4.

Complexity of algorithms

Tìm kiếm & sắp xếp

2


Khái niệm về tìm kiếm




Tìm kiếm là quá trình tìm một phần tử dữ liệu có một thành
phần khóa (Key), có kiểu dữ liệu là T nào đó, các thành
phần còn lại là thông tin (Info) liên quan đến phần tử dữ
liệu đó cần thỏa mãn điều kiện tìm kiếm.



Mỗi phần tử dữ liệu có cấu trúc dữ liệu như sau:
typedef struct DataElement
{

T

Key;

InfoType Info;
} DataType;


Việc tìm kiếm một phần tử có thể diễn ra trên một dãy/mảng
(tìm kiếm nội) hoặc diễn ra trên một tập tin/ file (tìm kiếm
ngoại).

Tìm kiếm & sắp xếp

3



Các giải thuật
tìm kiếm nội
Tìm

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


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


Tìm kiếm tuyến tính – Tìm kiếm tuần tự


Ý tưởng:



Bắt đầu từ phần tử đầu tiên của danh sách, so sánh lần lượt từng phần tử của
danh sách với giá trị X cần tìm





Nếu có phần tử bằng X thì trả về vị trí tìm thấy, thuật toán dừng lại (thành công)



Nếu đến cuối danh sách mà không có phần tử nào bằng X, thuật toán dừng lại (không thành

công)

Thuật toán:









B1: i = 1 //Duyệt từ đầu mảng
B2: IF M[i] # X AND i<= N //Nếu chưa tìm thấy và cũng chưa duyệt hết mảng

B2.1: i++

B2.2: Lặp lại B2
B3: IF i <= N

Tìm thấy tại vị trí i
B4: ELSE

Không tìm thấy phần tử có giá trị X
B5: Kết thúc

Tìm kiếm & sắp xếp

6



Tìm kiếm tuyến tính
(sequential search)
5

Vị trí = 2

Khóa tìm
0

1

2

3

4

5

6

7

7 13 5 21 6

2

8 15


Tìm thành công
Số lần so sánh: 3
Tìm kiếm & sắp xếp

7


Tìm kiếm tuyến tính
(không tìm thấy)
5

Vị trí kế tiếp : i+1

Khóa tìm
0

1

2

3

4

5

6

7


7 13 5 21 6

2

8 15

Không tìm thấy
Số lần so sánh: 5
Kết luận : TÌm thấy một phần tử tại vị trí 2
Tìm kiếm & sắp xếp

8


Tìm kiếm tuyến tính
(không tìm thấy)
9
Khóa tìm
0

1

2

3

4

5


6

7

7 13 5 21 6

2

8 15

Không tìm thấy
Số lần so sánh: 8
Tìm kiếm & sắp xếp

9


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


Cài đặt thuật toán

int LinearSearch(int a[], int n, int x)
{
int i=0;
while(iif (i// a[i] là phần tử có
khoá x
return -1;

// tìm hết mảng nhưng không có x
}

Tìm kiếm & sắp xếp

10


Tìm kiếm tuyến tính
Phân tích thuật toán:
 Trường hợp tốt nhất khi phần tử đầu tiên của mảng có giá trị bằng X:
 Số phép gán: Gmin = 1
 Số phép so sánh: Smin = 2 + 1 = 3
 Trường hợp xấu nhất khi không tìm thấy phần tử nào có giá trị bằng
X:
 Số phép gán: Gmax = 1
 Số phép so sánh: Smax = 2N+1
 Trung bình:
 Số phép gán: Gavg = 1
 Số phép so sánh: Savg = (3 + 2N + 1) : 2 = N + 2

Tìm kiếm & sắp xếp

11


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.

Tìm kiếm & sắp xếp

12


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








B1: i = 0
B2: M[N] = X //Phần tử cầm canh
B3: IF M[i] # X
 B3.1: i++
 B3.2: Lặp lại B3
B4: IF i < N
 Tìm thấy tại vị trí i
B5: ELSE //i = N song đó chỉ là phần tử cầm canh
 Không tìm thấy phần tử có giá trị X
B6: Kết thúc

Tìm kiếm & sắp xếp


13


Tìm kiếm tuyến tính
int LinearSearch(int a[], int n, int x)
{
int i=0;
// mảng gồm N phần tử từ a[0]..a[N-1]
a[n] = x;
// thêm lính canh vào cuối dãy
while(a[i]!=x) i++;
if (ireturn -1;
// tìm hết mảng nhưng không có x
}
Tìm kiếm & sắp xếp

14


Tìm kiếm tuyến tính
Phân tích thuật toán cải tiến:
 Trường hợp tốt nhất khi phần tử đầu tiên của mảng có giá trị bằng X:
 Số phép gán: Gmin = 2
 Số phép so sánh: Smin = 1 + 1 = 2
 Trường hợp xấu nhất khi không tìm thấy phần tử nào có giá trị bằng
X:
 Số phép gán: Gmax = 2
 Số phép so sánh: Smax = (N+1) + 1 = N + 2

 Trung bình:
 Số phép gán: Gavg = 2
 Số phép so sánh: Savg = (2 + N + 2) : 2 = N/2 + 2

Tìm kiếm & sắp xếp

15


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


Đánh giá giải thuật:
Trường hợp



Số lần so sánh

Giải thích

Tốt nhất

1

Phần tử đầu tiên có giá trị x

Xấu nhất

n+1


Phần tử cuối cùng có giá trị x

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 tuần tự có độ phức tạp tính toán cấp n: T(n) = O(n)

Tìm kiếm & sắp xếp

16


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ử trong danh sách, do vậy đây là
phương pháp tổng quát nhất để tìm kiếm trên một
danh sách 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 đến tốc độ thực
hiện của thuật toán.

Tìm kiếm & sắp xếp


17


Tìm kiếm nhị phân


Tìm kiếm nhị phân


Đối với những dãy đã có thứ tự (giả sử thứ tự
tăng), các phần tử trong dãy có quan hệ
a[i-1] ≤ a[i] ≤ a[i+1]



Nếu x > a[i] thì x chỉ có thể xuất hiện trong đoạn
[a[i+1] ,a[N]] của dãy



Nếu x < a[i] thì x chỉ có thể xuất hiện trong đoạn
[a[0] ,a[i-1]] của dãy .

Tìm kiếm & sắp xếp

19


Tìm kiếm nhị phân

Ý tưởng:






Phạm vi tìm kiếm ban đầu của chúng ta là từ phần tử đầu tiên
của dãy (First = 1) cho đến phần tử cuối cùng của dãy (Last =
N).
So sánh giá trị X với giá trị phần tử đứng ở giữa của dãy M là
M[Mid].
 Nếu X = M[Mid]: Tìm thấy
 Nếu X < M[Mid]: Rút ngắn phạm vi tìm kiếm về nửa đầu của dãy
M (Last = Mid–1)
 Nếu X > M[Mid]: Rút ngắn phạm vi tìm kiếm về nửa sau của dãy
M (First = Mid+1)
Lặp lại quá trình này cho đến khi tìm thấy phần tử có giá trị X
hoặc phạm vi tìm kiếm của chúng ta không còn nữa (First >
Last).

Tìm kiếm & sắp xếp

20


Tìm kiếm nhị phân
Bước 1: First = VTĐ; Last = VTC;
Bước 2: Trong khi First ≤ Last lặp: //đoạn tìm kiếm chưa rỗng
Bước 21: mid = (First+Last)/2; // lấy mốc so sánh

Bước 22: Nếu a[mid] = x:
//Tìm thấy.
Dừng, vị trí xuất hiện: mid
Bước 23: Nếu a[mid] > x:
//tìm x trong dãy con aFirst...
amid -1
Last = mid - 1;
Ngược lại //tìm x trong dãy con amid +1 .. aLast
First = mid + 1;
//Hết lặp
Bước 3: Dừng, không tìm thấy.
Tìm kiếm & sắp xếp

21


Tìm kiếm nhị phân
Vi trí = 3

10

Khóa cần tìm bằng
nhỏ hơn
lớn
hơn hoặc bằng

Khóa tìm
0

1


2

2

5

8 10 12 13 15 18 21 24

First

3

4

5

6

7

8

mid

9

Last

Tìm thấy

Số lần so sánh: 4
Tìm kiếm & sắp xếp

22


Tìm kiếm nhị phân
int RecBinarySearch (T M[], int First, int Last, T X)//Đệ qui
{
if (First > Last)
return -1;
int Mid = (First + Last)/2;
if (X == M[Mid])
return Mid;
if (X < M[Mid])
return(RecBinarySearch(M, First, Mid – 1, X));
else
return(RecBinarySearch(M, Mid + 1, Last, X));
}
Tìm kiếm & sắp xếp

23


Tìm kiếm nhị phân






Phân tích thuật toán đệ quy:
Trường hợp tốt nhất khi phần tử ở giữa của mảng có giá trị bằng
X:
 Số phép gán: Gmin = 1
 Số phép so sánh: Smin = 2
Trường hợp xấu nhất khi không tìm thấy phần tử nào có giá trị
bằng X:
 Số phép gán: Gmax = log2N + 1




Số phép so sánh: Smax = 3log2N + 1

Trung bình:
 Số phép gán: Gavg = ½ log2N + 1


Số phép so sánh: Savg = ½(3log2N + 3)

Tìm kiếm & sắp xếp

24


Tìm kiếm nhị phân
Thuật toán không đệ quy:













B1: First = 1, Last = N
B2: IF (First > Last)
 B2.1: Không tìm thấy
 B2.2: Thực hiện Bkt
B3: Mid = (First + Last)/ 2
B4: IF (X = M[Mid])
 B4.1: Tìm thấy tại vị trí Mid
 B4.2: Thực hiện Bkt
B5: IF (X < M[Mid])
 B5.1: Last = Mid – 1
 B5.2: Lặp lại B3
B6: IF (X > M[Mid])
 B6.1: First = Mid + 1
 B6.2: Lặp lại B3
Bkt: Kết thúc

Tìm kiếm & sắp xếp

25



×