Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 19 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
19
Dung lượng
648,46 KB
Nội dung
Bài 13 Tìm kiếm- Search Bài tốn Input: Cho tập S phần tử, phần tử gồm khóa-giá trị (key-value) khóa k Output: Trong S có phần tử có khóa k hay khơng? Search Các phương pháp tìm kiếm Tìm kiếm (Sequence search) Tìm kiếm nhị phân (Binary search) Bảng băm (Hash table) Search Tìm kiếm Tập S phần tử lưu mảng danh sách liên kết Thuật tốn tìm kiếm: • Xuất phát từ phần tử đầu dãy, thực so sánh khóa với k Nếu trùng dừng lại, khơng trùng lặp lại với phần tử • Q trình dừng lại tìm thấy khơng phần tử => Khi thơng báo khơng tìm thấy Search Tìm kiếm Ví dụ 1: Cho dãy S: 45 34 13 43 Tìm xem dãy có phần tử k=33 Q trình tìm kiếm 45 34 13 43 Bước Bước Bước Bước Bước Bước Bước Bước 11 11 Bước • Khơng tìm thấy Search Tìm kiếm Ví dụ 2: Cho dãy S: 45 34 13 43 Tìm xem dãy có phần tử k=13 Quá trình tìm kiếm 45 34 13 43 11 11 Bước Bước Bước Bước Bước • Tìm thấy, vị trí Search Tìm kiếm Thuật toán Input: Cho dãy S phần tử, phần tử key value Một khóa k Output: Trong S có phần tử có khóa k hay khơng? found = 0; i =1; while ((chưa duyệt hết S ) && (found= =0) ){ if (S[i].key == k) found =1; i = i+1; //Chuyển sang phần tử } return found; Search Tìm kiếm Thời gian chạy: Trong trường hợp xấu thuật toán phải duyệt qua tất phần tử S Vậy thời gian chạy O(n) Search Tìm kiếm nhị phân Tập S tổ chức lưu trữ dựa mảng Tập S tổ chức lưu trữ dạng nhị phân Search 2.1 Tìm kiếm nhị phân mảng Các phần tử S lưu trữ mảng xếp theo thứ tự tăng dần (giảm dần) giá trị khóa (key) Thuật tốn tìm kiếm nhị phân thiết kế dựa chiến lược chia để trị Thuật tốn: So sánh khóa k với khóa phần tử dãy • Nếu trùng thơng báo tìm thấy dừng • Nếu k> gọi đệ qui tìm nửa cuối dãy • Nếu k< gọi đệ qui tìm nửa đầu dãy • Q trình tìm phải tìm dãy rỗng dừng lại thơng báo khơng tìm thấy Search 2.1 Tìm kiếm nhị phân mảng •Ví dụ 1: Cho dãy Tìm phần tử k=6 11 14 16 18 19 Bước1: 6< 7 Bước 2: 6> Bước 3: 6> Bước 4: 6< Rỗng Khơng tìm thấy Bước 5: Search 10 2.1 Tìm kiếm nhị phân mảng • Ví dụ 2: Cho dãy Tìm phần tử k=5 11 14 16 18 19 Bước1: 5< 7 Bước 2: 5> Tìm thấy Bước 3: 5= Search 11 2.1 Tìm kiếm nhị phân mảng • Thuật toán: Algorithm BinarySearch(S, k, n); Found = 0; i = 1; j = n; while(i 10 -1 Ví dụ: Cây tìm kiếm nhị phân 14 Cây tìm kiếm nhị phân (Binary search tree) < > = Search 15 2.2 Tìm kiếm TKNP •Ví dụ: Find(4) < > = Search 12 16 Cấu trúc Node biểu diễn nhị phân Phương thức Thuộc tính Keys key T elem Node *Parent Node *Left Node *Right Chú ý: Keys tập giá trị có thứ tự Search Node *Parent() Node *Left() Node *Right() void setLeft(Node*) void setRight(Node*) void setParent(Node *) int hasLeft() int hasRight() Object getElem() void setElem(T o) void setKey(Keys k) Keys getKey() 17 Cấu trúc TKNP Thuộc tính Các phương thức truy cập: Node * root Node *root() Phương thức int size() int isEmpty() int isInternal(Node*) int isExternal(Node*) int isRoot(Node*) void preOrder(Node*) void inOrder(Node*) void postOrder(Node*) Node*TreeSearch(Keys, Node*) Node* InsertTree(Keys, T) void Remove(Keys) Search 18 Thuật tốn tìm kiếm Tìm có nút có khóa k khơng? Thuật tốn Xuất phát từ nút gốc So sánh giá trị khóa nút gốc với k Nếu giá trị =k trả lại đ/c nút dừng lại Nếu giá trị k tiếp tục tìm trái Quá trình tìm dừng lại tìm thấy phải tìm rỗng, trả lại địa nút mà thuật toán dừng lại Search 19 Thuật toán giả mã Node* TreeSearch(Keys k, Node* v) if(v==NULL) return v; else if (k < v->getKey()) return TreeSearch(k, v->Left()); else if (k == v->getKey()) return v; else // k > v->getKey() return TreeSearch(k, v->Right()); Search 20 Ví dụ < > = Tìm giá trị cây: Gọi T.TreeSearch(4, T.root()) Gọi T.TreeSearch(4, T.root()->Left())) Gọi T.TreeSearch(4, T.root()->Left()->Right()) Search 21 Phân tích thuật tốn Là thuật tốn đệ qui, Mỗi lần gọi đệ qui thực số phép tốn khơng đổi, lần gọi đệ qui cần thời gian O(1) Thực gọi đệ qui dọc theo nút, nút gốc, lần gọi đệ qui xuống mức Do số nút tối đa mà phải tới không vượt chiều cao h Thời gian chạy O(h) Cây T Trong trường hợp xấu có chiều cao bao nhiêu? Search 22 Một số trường hợp Cây có trái phải 12 Chiều cao số nút 15 Cây hoàn chỉnh Chiều cao log2n Search 12 23 Bổ sung nút vào cây- Insertion Sau bổ sung thỏa mãn tính chất TKNP Bổ sung nút với khóa k value x Thực tìm kiếm k > > Giả sử k khơng có Nếu rỗng gán nút gốc Ngược lại, kiểm tra Nếu khóa k< khóa gốc chèn nút bến trái Nếu khóa k> khóa gốc chèn nút bên phải < cho nút vào nút vào Search 24 Hàm bổ sung nút vào cây- Insertion Sau bổ sung thỏa mãn tính chất TKNP void InsertNode(Node *&root, Node *newNode){ if (root== NULL) root = newNode; else if (newNode->getKey()getKey()) InsertNode(root->Left(), newNode); else InsertNode(root->Right(), newNode); } Search 25 Ví dụ < > = Search 26 Xóa – Sau xóa nút, thỏa mãn tính chất TKNP Xảy hai khả năng: < Nút cần xóa nút Nút cần xóa nút ngồi Xóa nút yêu cầu giải lỗ hổng bên Để thực thao tác remove(k), Chúng ta tìm kiếm đến nút có khóa k Giả sử khóa k có cây, ta đặt v nút lưu trữ k > v w Search 27 Xóa nút ngồi < Xóa bỏ nút V > Search v 28 Xóa nút v có trái phải Loại bỏ v thay v vào vai trò v Ví dụ: xóa bỏ < > v w < > v 8 Search 29 Xóa nút v có hai nút trái phải Xóa nút thay nút có khóa lớn khóa nhỏ khóa (được gọi "nút tiền nhiệm" -nút cực phải trái) nút nhỏ khóa lớn (được gọi "nút kế vị" - nút cực trái phải) Cũng tìm nút tiền nhiệm nút kế vị đổi chỗ với nút cần xóa sau xóa Vì nút kiểu có hai nên việc xóa quy hai trường hợp trước Ví dụ: xóa bỏ Search v w z v 30 Ví dụ • Xóa phần tử 3 v w 12 10 v 12 w 10 Search 31 Thuật toán giả mã Xây dựng phương thức duyệt theo thứ tự giữa, hàm trả lại điạ nút thăm Xây dựng hàm xóa bỏ nút Search 32 void Remove(Node*& node) { if (node->Left() == NULL) { Node* temp = node; node = node->Right(); delete temp; } else if (node->Right() == NULL) { Node* temp = node; node = node->Left(); delete temp; } else { Node** temp = &(node->Left()); while ((*temp)->Right() != NULL) { temp = &((*temp)->right); } node->setKey ((*temp)-> getKey()); node->setElem ((*temp)-> getElem()); Remove(*temp); } } Search 33 Hàm duyệt theo thứ tự trả lại đ/c nút thăm void InOrder(Node*v, Node *first, int &kt){ if(v!=null && kt!=1){ InOrder(v.Left(),first, kt); if(kt==0){ first = v; kt=1; } InOrder(v.Right(),first, kt); } } Search 34 Ví dụ: Mơ tả bước xóa bỏ nút có key=58? 58 31 90 62 25 12 75 64 63 Search 35 Đánh giá thời gian Xem xét việc cài đặt từ điển có n mục cài dặt nhị phân tìm kiếm với chiều cao h Bộ nhớ sử dụng O(n) Phương thức find, insert remove thời gian O(h) Trong trường hợp xấu chiều cao O(n) trường hợp tốt O(log n) Search 36 Bài tập Xây dựng lớp tìm kiếm nhị phân Sử dụng lớp tìm kiếm nhị phân xây dựng chương trình tra cứu từ điển có chức sau: Đọc liệu từ điển nạp vào từ tệp Bổ sung từ vào Xóa bỏ từ khỏi Tìm kiếm từ Lưu vào tệp Search 37 Hết Search 38 ... return TreeSearch(k, v->Right()); Search 20 Ví dụ < > = Tìm giá trị cây: Gọi T.TreeSearch(4, T.root()) Gọi T.TreeSearch(4, T.root()->Left())) Gọi T.TreeSearch(4, T.root()->Left()->Right()) Search. .. Search Tìm kiếm Ví dụ 2: Cho dãy S: 45 34 13 43 Tìm xem dãy có phần tử k =13 Q trình tìm kiếm 45 34 13 43 11 11 Bước Bước Bước Bước Bước • Tìm thấy, vị trí Search Tìm kiếm Thuật toán Input: Cho dãy... tìm thấy Search Tìm kiếm Ví dụ 1: Cho dãy S: 45 34 13 43 Tìm xem dãy có phần tử k=33 Quá trình tìm kiếm 45 34 13 43 Bước Bước Bước Bước Bước Bước Bước Bước 11 11 Bước • Khơng tìm thấy Search Tìm