Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 23 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
23
Dung lượng
293,82 KB
Nội dung
Chương (1) : Giải Thuật Tìm Kiếm Giảng viên : Nguyễn Minh Thành Email : thanhnm@itc.edu.vn Nội Dung Giới thiệu II Giải thuật tìm kiếm III Tìm kiếm tuyến tính IV Tìm kiếm nhị phân I Nguyễn Minh Thành I Giới Thiệu Tìm kiếm : duyệt danh sách lấy phần tử thoả tiêu chuẩn cho trước Là thao tác phổ biến máy tính ứng dụng Tìm kiếm dịng CSDL Tìm kiếm hồ sơ, tập tin Tìm kiếm người danh sách … Việc tìm kiếm nhanh thơng tin lượng lớn thông tin điều cần thiết Các giải thuật tìm kiếm Nguyễn Minh Thành II Giải thuật tìm kiếm Khảo sát việc tìm kiếm thường mảng danh sách Có nhiều loại : Tìm kiếm tuyến tính (tuần tự) Tìm kiếm nhị phân … Cấu trúc : Input Mảng A gồm n phần tử Giá trị x cần tìm Output Vị trí x A -1 không tồn x Thao tác So sánh Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính Có loại tìm kiếm tuyến tính : Vét cạn (exhaustive) Dùng lính canh (sentinel) Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Vét Cạn Thuật tốn : Lần lượt so sánh x với phần tử mảng A gặp phần tử cần tìm, hết mảng Ví dụ: A = {1, 25, 6, 5, 2, 37, 40}, x = Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Vét Cạn Cài đặt : int LinearExhaustive(int a[], int N, int x) { int i=0; while ((i Số phép so sánh tăng/giảm tuyến tính theo số phần tử Vậy độ phức tạp thuật toán : O(n) Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Lính Căn Trong thuật tốn vét cạn, có điều kiện kiểm tra: Có thể bỏ việc kiểm tra điều kiện cuối mảng cách dùng “lính canh” Lính canh phần tử có giá trị với phần tử cần tìm đặt cuối mảng Thuật tốn lính 10 Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Lính Căn 11 Thuật tốn lính Tìm từ đầu mảng tìm thấy x (chắc chắn tìm thấy x) Nếu x tìm thấy vị trí lính canh x khơng thuộc mảng A Ngược lại trả vị trí x mảng A Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Lính Căn Cài đặt : int LinearSentinel(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 phần tử thứ N+1 while (a[i]!=x ) i++; if (i==N) return -1; // tìm hết mảng khơng có x else return i; // tìm thấy x vị trí i } 12 Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Lính Căn Cài đặt : int LinearSentinel(int a[], int n, int x) { a[n] = x; //đặtlínhcanh for (int i=0; ;i++) if (a[i] == x) break; if(i==n) i=-1; return i; } 13 Nguyễn Minh Thành III Tìm Kiếm Tuyến Tính – Lính Căn Số phép so sánh trường hợp xấu : n+2 Vậy độ phức tạp thuật toán O(n) Tuy nhiên, thực nghiệm cho thấy trường hợp n lớn, thời gian tìm kiếm giảm dùng phương pháp lính canh Với n=15000: nhanh khoảng 20% (0.22s so với 0.28s) 14 Nguyễn Minh Thành IV Tìm Kiếm Nhị Phân Khi mảng thứ tự, tận dụng điều ta giảm số thao tác cho thuật tốn tìm kiếm Thuật tốn tìm kiếm nhị phân Input: Dãy A, n phần tử xếp Giá trị x cần tìm Output: giống với thuật tốn tìm kiếm 15 Nguyễn Minh Thành IV Tìm Kiếm Nhị Phân 16 Ý tưởng So sánh x với phần tử mảng A Nếu x phần tử dừng Nếu khơng : xác định xem x thuộc nửa trái hay nửa phải A Lặp lại bước với nửa xác định Nguyễn Minh Thành IV Tìm Kiếm Nhị Phân Ví dụ : tìm x = 41 x x 14 16 19 22 41 46 51 63 71 10 l Tìm thấy x vị trí m r m m 17 x Nguyễn Minh Thành IV Tìm Kiếm Nhị Phân Ví dụ : tìm x = 45 x x x x 14 16 19 22 41 46 51 63 71 10 l m m r l > r: Kết thúc: Khơng tìm thấy m m 18 Nguyễn Minh Thành IV Tìm Kiếm Nhị Phân Các bước giải thuật Bước 1: left = 1; right = N; // tìm kiếm tất phần tử Bước 2: mid = (left+right)/2; // lấy mốc so sánh So sánh a[mid] với x, có khả : a[mid] = x: Tìm thấy Dừng a[mid] > x: //tìm tiếp x dãy aleft amid -1 right =mid - 1; a[mid] < x: //tìm tiếp x dãy amid +1 aright left = mid + 1; Bước 3: Nếu left