1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Tai lieu giao khoa chuyen tin quyen 2 bq phan 1 62

112 0 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 112
Dung lượng 0,98 MB

Nội dung

Hồ sĩ đàm (Chủ biên) đỗ đức đông lê minh hoàng nguyễn hùng tài liệu giáo khoa chuyên tin Nhà xuất giáo dục việt nam Công ty Cổ phần dịch vụ xuất Giáo dục Hà Nội - Nhà xuất Giáo dục Việt Nam giữ quyền công bố tác phẩm 349-2009/CXB/43-644/GD M4 sè : 8I746H9 LỜI NÓI ðẦU Bộ Giáo dục ðào tạo ban hành chương trình chun tin học cho lớp chuyên 10, 11, 12 Dựa theo chun đề chun sâu chương trình nói trên, tác giả biên soạn sách chuyên tin học, bao gồm vấn ñề cấu trúc liệu, thuật tốn cài đặt chương trình Bộ sách gồm ba quyển, 1, Cấu trúc bao gồm: phần lí thuyết, giới thiệu khái niệm bản, cần thiết trực tiếp, thường dùng nhất; phần áp dụng, trình bày tốn thường gặp, cách giải cài đặt chương trình; cuối tập Các chuyên ñề sách lựa chọn mang tính hệ thống từ ñến chuyên sâu Với trải nghiệm nhiều năm tham gia giảng dạy, bồi dưỡng học sinh chuyên tin học trường chun có truyền thống uy tín, tác giả ñã lựa chọn, biên soạn nội dung bản, thiết yếu mà sử dụng ñể dạy học với mong muốn sách phục vụ không cho giáo viên học sinh chuyên PTTH mà cho giáo viên, học sinh chuyên tin học THCS làm tài liệu tham khảo cho việc dạy học Với kinh nghiệm nhiều năm tham gia bồi dưỡng học sinh, sinh viên tham gia kì thi học sinh giỏi Quốc gia, Quốc tế Hội thi Tin học trẻ Toàn quốc, Olympiad Sinh viên Tin học Tồn quốc, Kì thi lập trình viên Quốc tế khu vực ðơng Nam Á, tác giả lựa chọn giới thiệu tập, lời giải có định hướng phục vụ cho không học sinh mà sinh viên làm tài liệu tham khảo tham gia kì thi Lần đầu tập sách biên soạn, thời gian trình độ có hạn chế nên chắn cịn nhiều thiếu sót, tác giả mong nhận ý kiến đóng góp bạn đọc, ñồng nghiệp, sinh viên học sinh ñể sách ñược ngày hoàn thiện Các tác giả Chuyên ñề KIỂU DỮ LIỆU TRỪU TƯỢNG VÀ CẤU TRÚC DỮ LIỆU Kiểu liệu trừu tượng mơ hình tốn học với thao tác định nghĩa mơ hình Kiểu liệu trừu tượng khơng tồn ngơn ngữ lập trình mà dùng để tổng qt hóa tóm lược thao tác ñược thực liệu Kiểu liệu trừu tượng ñược cài ñặt máy tính cấu trúc liệu: Trong kỹ thuật lập trình cấu trúc (Structural Programming), cấu trúc liệu biến với thủ tục hàm thao tác biến Trong kỹ thuật lập trình hướng đối tượng (ObjectOriented Programming), cấu trúc liệu kiến trúc thứ bậc lớp, thuộc tính phương thức tác động lên đối tượng hay vài thuộc tính đối tượng Trong chương này, khảo sát vài kiểu liệu trừu tượng cách cài ñặt chúng cấu trúc liệu Những kiểu liệu trừu tượng phức tạp mơ tả chi tiết thuật toán thấy cần thiết Danh sách 1.1 Khái niệm danh sách Danh sách tập thứ tự phần tử kiểu ðối với danh sách, người ta có số thao tác: Tìm phần tử danh sách, chèn phần tử vào danh sách, xóa phần tử khỏi danh sách, xếp lại phần tử danh sách theo trật tự v.v… Việc cài đặt danh sách máy tính tức tìm cấu trúc liệu cụ thể mà máy tính hiểu để lưu phần tử danh sách đồng thời viết đoạn chương trình mơ tả thao tác cần thiết danh sách Vì danh sách tập thứ tự phần tử kiểu, ta ký hiệu  kiểu liệu phần tử danh sách, cài đặt cụ thể,  kiểu liệu chương trình dịch chấp nhận (Số nguyên, số thực, ký tự, …) 1.2 Biểu diễn danh sách mảng Khi cài ñặt danh sách mảng chiều , ta cần có biến nguyên  lưu số phần tử có danh sách Nếu mảng ñược ñánh số bắt ñầu từ phần tử danh sách cất giữ mảng phần tử ñược ñánh số từ tới :   a) Truy c c p ph ph n t t m mng Việc truy cập phần tử vị trí  mảng thực dễ dàng qua phần tử  Vì phần tử mảng có kích thước lưu trữ liên tục nhớ, việc truy cập phần tử thực phép tốn tính địa phần tử có thời gian tính tốn số Vì cài đặt mảng, việc truy cập phần tử danh sách vị trí có độ phức tạp   b) Chèn ph lượt trả nút chứa khóa nhỏ lớn nhánh BST gốc ñây ta giả thiết nhánh BST gốc khác rỗng: d ) (ở function Minimum(x: PNode): PNode; //Khóa nhỏ nằm nút cực trái begin while x^.left ≠ nilT //ði sang nút trái chừng cịn x := x^.left; Result := x; end; function Maximum(x: PNode): PNode; //Khóa lớn nằm nút cực phải begin while x^.right ≠ nilT //ði sang nút phải chừng cịn x := x^.right; Result := x; end; d) Tìm nút liE liEn trF4 trF4c nút liE liEn sau ðơi phải tìm nút ñứng liền trước liền sau nút duyệt BST theo thứ tự Trước hết ta xét viết hàm B!l""!  trả nút ñứng liền trước nút , xét hai trường hợp:   Nếu có nhánh trái trả nút cực phải nhánh trái: D"@ z y @ xE # Nếu khơng có nhánh trái từ , ta dần lên phía gốc gặp nút chứa nhánh phải dừng lại trả nút function Predecessor(x: PNode): PNode; begin if x^.left ≠ nilT then //x có nhánh trái Result := Maximum(x^.left) //Trả nút cực phải trái else repeat Result := x^.parent; //Nếu x gốc x nhánh phải thoát if (Result = nilT) or (x = Result^.right) then Break; x := Result; //Nếu khơng tiếp lên phía gốc until False; end; 57 Hàm k@ll""!  trả nút liền sau nút có cách làm tương tự ta đổi vai trị # D[, y@ y @: function Successor(x: PNode): PNode; begin if x^.right ≠ nilT then //x có nhánh phải Result := Minimum(x^.right) //Trả nút cực trái phải else repeat Result := x^.parent; //Nếu x gốc x nhánh trái if (Result = nilT) or (x = Result^.left) then Break; x := Result; //ði tiếp lên phía gốc until False; end; e) Tìm ki* ki*m Phép tìm kiếm nhận vào nút khóa  Nếu khóa  có nhánh BST gốc trả nút chứa khóa , khơng trả  Phép tìm kiếm BST cài đặt hàm k !l, hàm ñược xây dựng dựa nguyên lý chia ñể trị: Nếu nút chứa khóa  hàm đơn giản trả nút , khơng việc tìm kiếm ñược tiến hành tương tự trái phải tùy theo nút chứa khóa nhỏ hay lớn : //Hàm Search trả nút chứa khóa k, trả nilT khơng tìm thấy khóa k nhánh gốc x function Search(x: PNode; const k: TKey): PNode; begin while (x ≠ nilT) and (x^.key ≠ k) //Chừng chưa tìm thấy if k < x^.key then x := x^.left //k chắn không nằm phải, tìm trái else x := x^.right; //k chắn không nằm trái, tìm phải Result := x; end; 58 f) Chèn Chèn khóa  vào BST tức thêm nút chứa khóa  BST móc nối nút vào BST cho ñảm bảo cấu trúc BST Phép chèn ñược thực dựa nguyên lý chia ñể trị: Bài tốn chèn  vào BST quy toán chèn  vào trái hay phải, tùy theo khóa  nhỏ hay lớn khóa chứa nút gốc Trường hợp sở  ñược chèn vào nhánh rỗng, ta việc tạo nút mới, móc nối nút vào nhánh rỗng ñặt khóa  vào nút ñó 3 7 8 Hình 1.11 Cây nhị phân tìm kiếm trước sau chèn khóa { | Trước tiên ta viết thủ tục k#B !8 F8 =# ñể chỉnh lại liên kết cho nút F trở thành nút nút B !: procedure SetLink(ParentNode, ChildNode: PNode; InLeft: Boolean); begin ChildNode^.parent := ParentNode; if InLeft then ParentNode^.left := ChildNode //InLeft = True: Cho ChildNode thành nút trái ParentNode else ParentNode^.right := ChildNode; //InLeft = False: Cho ChildNode thành nút phải ParentNode end; Khi thủ tục chèn nút x vào BST viết sau //Chèn k vào BST, trả nút chứa k 59 function Insert(k: TKey): PNode; var x, y: PNode; begin y := nilT; x := root; //Bắt ñầu từ gốc while x ≠ nilT begin y := x; if k < x^.key then x := x^.left //Chèn vào nhánh trái else x := x^.right; //Chèn vào nhánh phải end; New(x); //Tạo nút chứa k x^.key := k; x^.left := nilT; x^.right := nilT; SetLink(y, x, k < y^.key); //Móc nối vào BST if root = nilT then root := x; //Cập nhật lại gốc nút ñầu tiên chèn vào Result := x; end; g) Xóa Việc xóa nút BST thực chất xóa ñi khóa chứa nút Phép xóa ñược thực sau:   Nếu có hai nhánh con, ta lấy nút (nếu có) lên thay cho xóa nút Nếu có hai nhánh con, ta xác ñịnh nút > nút cực phải nhánh trái (hoặc nút cực trái phải), đưa khóa chứa nút > lên nút xóa nút > Chú ý nút > chắn khơng có đủ hai nút con, việc xóa quy trường hợp (h.1.22) 60 > > 7 Hình 1.22 Xóa nút khỏi BST procedure Delete(x: PNode); var y, z: PNode; begin if (x^.left ≠ nilT) and (x^.right ≠ nilT) then //x có hai nhánh begin y := Maximum(x^.left); //Tìm nút cực phải trái x^.key := y^.key; //ðưa khóa nút y lên nút x x := y; end; //Vấn đề xóa nút x có nhiều nhánh con, xác định y nút (nếu có) x if x^.left ≠ nilT then y := x^.left else y := x^.right; z := x^.parent; //z cha x //cho y làm z thay cho x SetLink(z, y, z^.left = x); if x = root then root := y; //Trường hợp nút x bị hủy gốc cập nhật lại gốc y Dispose(x); //Giải phóng nhớ cấp cho nút x end; h) Phép quay Phép quay phép chỉnh lại cấu trúc liên kết BST, có hai loại: quay trái (left rotation) quay phải (right rotation) Khi ta thực phép quay trái nút , giả thiết nút phải > d  Trên gốc , phép quay trái ñưa > lên làm gốc mới, 61 trở thành nút trái > nút trái > trở thành nút phải Phép quay gọi quay theo liên kết } G > Ngược lại, phép quay phải thực gốc > mà nút trái > d  Sau phép quay phải, ñược ñưa lên làm gốc nhánh, > trở thành nút phải nút phải > trở thành nút trái Phép ~ quay gọi quay theo liên kết > G Dễ thấy sau phép quay, ràng buộc quan hệ thứ tự khóa chứa ñảm bảo cho BST Hình 5.4 mơ tả hai phép quay nhị phân tìm kiếm c c > Quay phải   Quay trái >  € €  Hình 1.23 Phép quay Các thuật toán quay trái quay phải viết sau: procedure RotateLeft(x: PNode); var y, z, branch: PNode; begin y := x^.right; z := x^.parent; branch := y^.left; SetLink(x, branch, False); //Cho branch trở thành phải x SetLink(y, x, True); //Cho x trở thành trái y SetLink(z, y, (z^.left = x)); //Móc nối y vào làm z thay cho x if root = x then root := y; //Cập nhật lại gốc trước ñây x gốc end; 62 procedure RotateRight(y: PNode); var x, z, branch: PNode; begin x := y^.left; z := y^.parent; branch := x^.right; SetLink(y, branch, True); //Cho branch trở thành trái y SetLink(x, y, False); //Cho y trở thành phải x SetLink(z, x, z^.left = y); //Móc nối x vào làm z thay cho y if root = y then root := x; //Cập nhật lại gốc trước ñây y gốc end; Dễ thấy BST sau phép quay BST Chúng ta viết thao tác ‚!  tổng quát hơn: Với d ! , > xE  ! , phép ‚!  quay theo liên kết > ƒ để đẩy nút lên phía gốc (độ sâu giảm 1) kéo nút > xuống sâu mức làm nút procedure UpTree(x: PNode); var y, z, branch: PNode; begin y := x^.parent; //y^ nút cha x^ z := y^.parent; //z^ nút cha y^ if x = y^.left then //Quay phải begin branch := x^.right; SetLink(y, branch, True); //Chuyển nhánh gốc branch^ x^ sang làm trái y^ SetLink(x, y, False); //Cho y^ làm phải x^ end else //Quay trái begin branch := x^.left; SetLink(y, branch, False); //Chuyển nhánh gốc branch^ x^ sang làm phải y^ SetLink(x, y, True); //Cho y^ làm trái x^ end; SetLink(z, x, z^.left = y); //Móc nối x^ vào làm z^ thay cho y^ if root = y then root := x; //Cập nhật lại gốc BST trước ñât y^ gốc 63 end; 5.3 Hiệu lực thao tác nhị phân tìm kiếm Có thể chứng minh ñược thao tác y@ , y @ , B!l""!, k@ll""!, k !l, ="! có thời gian thực $ với  chiều cao nhị phân tìm kiếm Hơn nữa, trường hợp xấu nhất, thao tác có thời gian thực  Vậy lưu trữ  khóa nhị phân tìm kiếm cấu trúc BST tốt cấu trúc nhị phân gần hoàn chỉnh (có chiều cao thấp nhất:  _%' `) cịn cấu trúc BST tồi ñể biểu diễn cấu trúc nhị phân suy biến (có chiều cao   C ) 5.4 Cây nhị phân tìm kiếm tự cân a) Tính cân b+ b+ng ðể tăng tính hiệu thao tác BST, cách chung cố gắng giảm chiều cao Với BST gồm  nút, dĩ nhiên giải pháp lý tưởng giảm chiều cao xuống cịn _%' ` (cây nhị phân gần hồn chỉnh) điều thường làm ảnh hưởng nhiều tới thời gian thực giải thuật Người ta nhận thấy muốn nhị phân thấp phải cố gắng giữ cân (về chiều cao số nút) hai nhánh nút Chính ý tưởng ban ñầu ñể giảm chiều cao BST xuất phát từ kỹ thuật cân cây, từ người ta xây dựng cấu trúc liệu nhị phân tìm kiếm có khả tự cân (self-balancing binary search tree) với mong muốn giữ chiều cao BST ln đại lượng $%'  b) M8t s! s! d9ng BST tL tL cân b+ b+ng  Cây AVL Một phát kiến ñầu tiên cấu trúc BST tự cân AVL [1] Trong nhánh AVL, chiều cao nhánh trái nhánh phải không Mỗi nút AVL chứa thêm thông tin hệ số cân (ñộ lệch chiều cao nhánh trái nhánh phải) Ngay sau phép chèn/xóa, hệ số cân số nút ñược cập nhật lại 64 phát nút có hệ số cân w ;, phép quay ñược thực ñể cân ñộ cao hai nhánh nút Một AVL có độ cao  có khơng   V C nút Ở ñây   V số fibonacci thứ   V Các tác giả chứng minh ñược chiều cao AVL có  nút ñại lượng „ EXX7X %'  ; C 7EV;e  Cây ñỏ ñen Một dạng khác BST tự cân ñỏ ñen (Red-Black tree) [4] Mỗi nút ñỏ ñen chứa thêm bit màu (đỏ đen) Ngồi tính chất BST, ñỏ ñen thỏa mãn tính chất sau ñây:      Mọi nút tơ màu (đỏ đen) Nút gốc !x có màu đen Nút x có màu đen Nếu nút tơ màu đỏ hai nút phải tơ màu đen Với nút, tất đường ñi từ nút ñó ñến nút hậu duệ có số lượng nút đen Tương tự AVL, kèm với phép chèn/xóa ñỏ ñen thao tác tô màu cân Người ta chứng minh ñược chiều cao đỏ đen có  nút khơng vượt ; %'   Trên thực tế ñỏ ñen nhanh AVL phép chèn xóa chậm phép tìm kiếm  Cây Splay Còn nhiều dạng BST tự cân khác ý tưởng thú vị Splay [35] Cây Splay trì cân mà không cần thêm thông tin phụ trợ nút Phép “làm bẹp” ñược thực có lệnh truy cập, nút thường xun truy cập ñược ñẩy dần lên gần gốc ñể có tốc ñộ truy cập nhanh Các phép tìm kiếm, chèn xóa Splay thực thời gian $%'  (ñánh giá bù trừ) Trong trường hợp tần suất thực phép tìm kiếm khóa hay cụm khóa cao hẳn so với khóa khác, splay phát huy ñược ưu mặt tốc ñộ 65 c) V6n "E "E chN chNng minh lý thuy* thuy*t cài ": " :t Cây AVL ñỏ ñen thường đưa vào giảng dạy giáo trình cấu trúc liệu tính chất hai cấu trúc liệu dễ dàng chứng minh lý thuyết Cây Splay thường ñược sử dụng phần mềm ứng dụng tốc độ nhanh tính chất “nhanh truy cập lại” (quick to access again) Ba loại phổ biến thư viện hỗ trợ môi trường phát triển cao cấp ñể viết phần mềm ứng dụng Lập trình viên tùy chọn loại thích hợp để cài đặt giải vấn đề Trong trường hợp bạn lập trình thời gian hạn hẹp mà khơng có thư viện hỗ trợ (chẳng hạn kỳ thi lập trình), phải nói việc cài đặt loại kể khơng đơn giản dễ nhầm lẫn (bạn tham khảo tài liệu khác sở lý thuyết kỹ thuật cài ñặt loại kể trên) Nếu bạn cần sử dụng cấu trúc liệu phần mềm, theo bạn nên sử dụng thư viện sẵn có viết thư viện lớp mẫu (class template) thật cẩn thận ñể sử dụng lại Tơi khơng vào chi tiết loại ðiều bạn phải nhớ có tồn cấu trúc vậy, ñể ñánh giá thuật tốn có sử dụng BST, coi thao tác BST ñược thực thời gian $%'  Trong sau giới thiệu cấu trúc BST khác dễ cài ñặt hơn, dễ tùy biến hơn, tốc ñộ không thua thực tế: Cấu trúc Treap Bài tập 1.16 Q trình tìm kiếm BST coi ñường ñi xuất phát từ nút gốc Giáo sư X phát tính chất thú vị: Nếu đường q trình tìm kiếm kết thúc nút lá, ký hiệu # tập giá trị chứa nút nằm bên trái ñường ñi D tập giá trị chứa nút nằm bên phải ñường ñi Khi ñó L #8 > D, ta có N > Chứng minh phát giáo sư X ñúng phản ví dụ 1.17 Cho BST gồm  nút, bắt ñầu từ nút y@x , người ta gọi hàm k@ll""! ñể ñi sang nút liền sau duyệt qua nút y @x 66 Chứng minh thời gian thực giải thuật có thời gian thực $ Gợi ý: Thực  lời gọi k@ll""! lên tiếp ñơn giản duyệt qua liên kết cha/con BST liên kết tối đa lần ðiều tương tự chứng minh ñược ta bắt ñầu từ nút y @x gọi liên tiếp hàm B!l""! ñể ñi sang nút liền trước 1.18 Cho BST có chiều cao , nút (, người ta tìm nút + nút liền sau (: + z k@ll""!( , lại tìm nút … nút liền sau + ,… Chứng minh thời gian thực  lần phép k@ll""! thời gian $   1.19 (tree Sort) Người ta thực việc xếp dãy khóa nhị phân tìm kiếm: Chèn giá trị khóa vào nhị phân tìm kiếm sau duyệt theo thứ tự ðánh giá thời gian thực giải thuật trường hợp tốt nhất, xấu trung bình Cài đặt thuật tốn tree Sort 1.20 Viết thuật tốn k !l# để tìm nút chứa khóa lớn N  BST 1.21 Viết thuật toán k !lA để tìm nút chứa khóa nhỏ w  BST 1.22 Viết thủ tục yD nhận vào nút  dùng phép quay ñể chuyển nút  thành gốc BST 1.23 Viết thủ tục y#  nhận vào nút  dùng phép quay ñể chuyển nút  thành nút BST 1.24 Radix tree (cây tìm kiếm số) nhị phân nút chứa khơng chứa giá trị khóa, (người ta thường dùng giá trị ñặc biệt tương ứng với nút khơng chứa giá trị khóa sử dụng thêm bit đánh dấu nút khơng chứa giá trị khóa) Các giá trị khóa lưu trữ Radix tree dãy nhị phân, hay tổng quát kiểu liệu mã hóa dãy nhị phân Phép chèn khóa vào Radix tree ñược thực sau: Bắt ñầu từ nút gốc ta duyệt biểu diễn nhị phân khóa, gặp bit ñi sang nút trái gặp 67

Ngày đăng: 28/06/2023, 21:55