Tìm kiếm nhị phân trên mảng được sắp

Một phần của tài liệu Tài liệu ĐỀ CƯƠNG CHI TIẾT MÔN HỌC KỸ THUẬT LẬP TRÌNH doc (Trang 54 - 56)

II. Truyền tham số mảng cho hàm

2.Tìm kiếm nhị phân trên mảng được sắp

Phương pháp này chỉ áp dụng trên mảng đã được sắp. Ý tưởng có thể hình dung như sau:

Giả sử ta cần tìm kiếm c trong một đoạn từ vị trí L tới vị trí R trên một mảng a được sắp:

Biªn so¹n: NguyÔn M¹nh Cêng Trang 5 4

Khi đó, ta chia mảng a làm hai phần bởi điểm chia M: M = (L+R)/ 2

Ta áp dụng tìm kiếm trên 2 nửa của a. Tuy nhiên, do a đã được sắp nên chỉ có thể sảy ra 3 trường hợp sau:

[1]. Nếu a[M] = c thì ta đã tìm được c trong mảng. Vị trí của c là M.

[2]. Nếu a[M] > c thì c thuộc về nửa trái của mảng a. Khi đó ta áp dụng tìm kiếm trên nửa trái, tức là từ vị trí L tới M-1.

[3]. Nếu a[M] < c thì c thuộc về nửa phải của mảng a. Khi đó ta áp dụng tìm kiếm trên nửa phải, tức là từ vị trí M+1 tới R.

Việc tìm kiếm trên các nửa của a cũng áp dụng phương pháp chia đôi tương tự như trên. Như vậy, ngay từ đầu ta áp dụng tìm kiếm nhị phân trên toàn mảng a (L=0; R=n-1). Hàm tìm kiếm nhị phân lặp sau đây trả về giá trị -1 nếu không tìm thấy c trong a; ngược lại, nó trả về vị trí của c trong a.

int TKNP_Lap(int a[100], int n, int c) { int L, R, M; L =0; R = n-1; do { M = (L+R)/2; if (a[M] > c) L = M+1; if (a[M] < c) R = M-1; }

while (L<R && a[M]!=c);

if (a[M] ==c) return M; else

return -1; }

Rõ ràng là trong trường hợp này, việc áp dụng đệ quy là rất phù hợp. Sau đây ta xem xét khả năng áp dụng đệ quy với thiết kế sau:

B1: Suy biến trong trường hợp L > R hoặc a[M] = c. Khi đó - Nếu L > R thì không tìm được c trong a.

- Nếu a[M] = c thì trả về M là vị trí của c trong a.Ngược lại, trong trường hợp L <= R và a[M] ! = c. Khi đó: Ngược lại, trong trường hợp L <= R và a[M] ! = c. Khi đó:

- Nếu a[M] > c thì gọi đề quy trên đoạn [L, M-1]- Nếu a[M] < c thì gọi đề quy trên đoạn [M+1, R]. - Nếu a[M] < c thì gọi đề quy trên đoạn [M+1, R].

if (L > R) return -1; else

if (a[M] ==c) return M;

else

if (a[M] > c) return TKQD(a, n, c, L, M-1);

else return TKDQ(a, n, c, M+1, R);

Sau đây là code:

int TKNP_DQ(int a[100], int n, int c, int L, int R) { int M=(L+R)/2; if (L>R) return -1; else if (a[M]==c) return M; else if (a[M] > c) return TKNP_DQ(a, n, c, M+1, R); else return TKNP_DQ(a, n, c, L, M-1); }

Thuật toán tìm kiếm đệ quy trên mảng được sắp được đánh giá tương đối tốt. Độ phức tạp trong trường hợp tồi nhất là O(lg (n)). Phương pháp này không bao giờ dùng nhiều hơn lg(n) + 1 phép so sánh. Một phương pháp tìm kiếm hiệu quả hơn là tìm kiếm nội suy trên cây (ít hơn lg(lg(n)) +1 phép so sánh) không được đề cập trong bài giảng này.

Một phần của tài liệu Tài liệu ĐỀ CƯƠNG CHI TIẾT MÔN HỌC KỸ THUẬT LẬP TRÌNH doc (Trang 54 - 56)