Tài liệu tin học
TRƯỜNG ĐẠI HỌC ĐÀ LẠT KHOA CÔNG NGHỆ THÔNG TIN NGUYỄN THỊ THANH BÌNH NGUYỄN VĂN PHÚC GIÁO TRÌNH CẤU TRÚC DỮ LIỆU VÀ THUẬT GIẢI Dành cho sinh viên ngành công nghệ thông tin Đà Lạt 2010 LỜI NÓI ĐẦU Để đáp ứng nhu cầu học tập bạn sinh viên, sinh viên chuyên ngành công nghệ thông tin, Khoa Công Nghệ Thông Tin Trường Đại Học Đà Lạt tiến hành biên soạn giáo trình, giảng chương trình học Giáo trình soạn theo đề cương chi tiết môn Cấu Trúc Dữ Liệu Và Thuật Giải Khoa Công nghệ Thông tin, trường Đại học Đà Lạt Mục tiêu giáo trình nhằm giúp bạn sinh viên chun ngành có tài liệu đọng dùng làm tài liệu học tập Nội dung giáo trình gồm chương sau: Chương 1: trình bày cấu trúc liệu cây, nhấn mạnh cấu trúc liệu nhị phân tìm kiếm BST nhị phân tìm kiếm cân AVL phép tốn Chương 2: trình bày đồ thị, cấu trúc liệu dùng biểu diễn đồ thị số toán đồ thị Chương 3: trình bày cấu trúc liệu bảng băm, hàm băm, cách tổ liệu bảng băm nhằm phục vụ cho tốn tìm kiếm hiệu Chương 4: giới thiệu số phương pháp thiết kế giải thuật giúp sinh viên bước đầu làm quen với số phương pháp thiết kế giải thuật Mặc dù cố gắng nhiều trình biên soạn giáo trình, xong khơng khỏi cịn nhiều thiếu sót hạn chế Rất mong nhận đóng góp ý kiến quý báu sinh viên bạn đọc để giáo trình ngày hồn thiện Đà Lạt, ngày 30 tháng 08 năm 2010 Mục lục Chương I: Cây I Các thuật ngữ Định nghĩa Thứ tự nút Các thứ tự duyệt quan trọng Cây có nhãn biểu thức II Cây nhị phân (Binary Trees) Định nghĩa Vài tính chất nhị phân 10 Biểu diễn nhị phân 10 Duyệt nhị phân 10 Cài đặt nhị phân 11 IV Cây tìm kiếm nhị phân (Binary Search Trees) 13 Định nghĩa 13 Cài đặt tìm kiếm nhị phân 14 V Cây nhị phân tìm kiếm cân (Cây AVL) 22 Cây nhị phân cân hoàn toàn 22 Xây dựng nhị phân cân hoàn toàn 22 Cây tìm kiếm nhị phân cân (cây AVL) 23 Bài tập 33 Chương II: Đồ Thị 36 I Các định nghĩa 36 III Biểu diễn đồ thị 38 Biểu diễn đồ thị ma trận kề 38 Biểu diễn đồ thị danh sách đỉnh kề 40 IV Các phép duyệt đồ thị (traversals of Graph) 40 Duyệt theo chiều sâu (Depth-first search) 40 Duyệt theo chiều rộng (breadth-first search) 41 V Một số toán đồ thị 44 Bài tốn tìm đường ngắn từ đỉnh đồ thị 44 Bài tốn tìm bao đóng chuyển tiếp 48 Bài tốn tìm bao trùm tối thiểu (minimum-cost spanning tree) 49 Bài tập 54 Chương III: Bảng Băm 56 I Phương pháp băm 56 II Các hàm băm 58 Phương pháp chia 58 Phương pháp nhân 58 Hàm băm cho giá trị khoá xâu ký tự 59 III Các phương pháp giải va chạm 60 Phương pháp định địa mở 60 Phương pháp tạo dây chuyền 63 IV Cài đặt bảng băm địa mở 64 V Cài đặt bảng băm dây chuyền 67 VI Hiệu phương pháp băm 70 Bài tập 72 Chương IV: Một số phương pháp thiết kế thuật giải 74 I Phương pháp chia để trị 74 Mở đầu 74 Tìm kiếm nhị phân 75 Bài toán Min-Max 76 Thuật toán QuickSort 77 II Phương pháp quay lui 80 Mở đầu 80 Bài toán liệt kê dãy nhị phân độ dài n 81 Bài toán liệt kê hoán vị 81 Bài toán duyệt đồ thị theo chiều sâu (DFS) 82 III Phương pháp tham lam 84 Mở đầu 84 Bài toán người du lịch 85 Thuật toán Prim - Tìm bao trùm nhỏ 87 Bài toán túi sách 87 Bài tập 88 Tài liệu tham khảo 90 Chương I Cây Mục tiêu Sau học xong chương này, sinh viên phải: - Nắm vững khái niệm (trees) - Cài đặt thực phép toán Kiến thức cần thiết Để học tốt chương này, sinh viên phải nắm vững kỹ lập trình như: - Kiểu trỏ (pointer) - Các cấu trúc điều khiển, lệnh vòng lặp - Lập trình theo module (chương trình con) cách gọi chương trình - Lập trình đệ qui gọi đệ qui - Kiểu liệu trừu tượng danh sách Nội dung Trong chương nghiên cứu vấn đề sau: - Các thuật ngữ - Kiểu liệu trừu tượng Cây - Cây nhị phân - Cây tìm kiếm nhị phân - Cây nhị phân tìm kiếm cân AVL I Các thuật ngữ Cây tập hợp phần tử gọi nút (nodes) có nút phân biệt gọi nút gốc (root) Trên tập hợp nút có quan hệ, gọi mối quan hệ cha - (parenthood), để xác định hệ thống cấu trúc nút Mỗi nút, trừ nút gốc, có nút cha Một nút có nhiều nút khơng có nút Mỗi nút biểu diễn phần tử tập hợp xét có kiểu bất kỳ, thường ta biểu diễn nút kí tự, chuỗi số ghi vòng tròn Mối quan hệ cha biểu diễn theo qui ước nút cha dòng nút dòng nối đoạn thẳng Một cách hình thức ta định nghĩa cách đệ qui sau: Định nghĩa - Một nút đơn độc Nút nút gốc - Giả sử ta có n nút đơn độc k T1, , Tk với nút gốc tương ứng n1, , nk xây dựng cách cho nút n cha nút n1, , nk Cây có nút gốc nút n T1, , Tk gọi Tập rỗng coi gọi rỗng kí hiệu Ví dụ: xét mục lục sách Mục lục xem Hình I.1: Cây mục lục sách Nút gốc sách, có ba có gốc C1, C2, C3 Cây thứ có gốc C3 nút đơn độc hai (gốc C1 C2) có nút Nếu n1, , nk chuỗi nút cho ni nút cha nút ni+1, với i=1 k1, chuỗi gọi đường (hay ngắn gọn đường đi) từ n1 đến nk Độ dài đường định nghĩa số nút đường trừ Như độ dài đường từ nút đến khơng Nếu có đường từ nút a đến nút b ta nói a tiền bối (ancestor) b, b gọi hậu duệ (descendant) nút a Rõ ràng nút vừa tiền bối vừa hậu duệ Tiền bối hậu duệ nút khác với gọi tiền bối hậu duệ thực Trên nút gốc khơng có tiền bối thực Một nút khơng có hậu duệ thực gọi nút (leaf) Nút khơng phải ta cịn gọi nút trung gian (interior) Cây một nút với tất hậu duệ Chiều cao nút độ dài đường lớn từ nút tới Chiều cao chiều cao nút gốc Độ sâu nút độ dài đường từ nút gốc đến nút Các nút có độ sâu i ta gọi nút có mức i Theo định nghĩa nút gốc mức 0, nút nút gốc mức Ví dụ: hình I.1 ta có nút C2 có chiều cao Cây có chiều cao nút C3 có chiều cao Nút 2.1 có độ sâu Các nút C1,C2,C3 mức Thứ tự nút Nếu ta phân biệt thứ tự nút nút gọi có thứ tự, thứ tự qui ước từ trái sang phải Như vậy, kể thứ tự hai sau hai khác nhau: Hình I.2: Cây có thứ tự khác Trong trường hợp ta không phân biệt rõ ràng thứ tự nút ta gọi khơng có thứ tự Các nút nút cha gọi nút anh em ruột (siblings) Quan hệ "trái sang phải" anh em ruột mở rộng cho hai nút theo qui tắc: a, b hai anh em ruột a bên trái b hậu duệ a "bên trái" hậu duệ b Các thứ tự duyệt quan trọng Duyệt qui tắc cho phép qua tất nút nút lần, danh sách liệt kê nút (tên nút giá trị chứa bên nút) theo thứ tự qua gọi danh sách duyệt Có ba cách duyệt quan trọng: Duyệt tiền tự (preorder), duyệt trung tự (inorder), duyệt hậu tự (posorder) - Cây rỗng danh sách duyệt rỗng coi biểu thức duyệt tiền tự, trung tự, hậu tự - Cây có nút danh sách duyệt gồm nút coi biểu thức duyệt tiền tự, trung tự, hậu tự - Ngược lại: giả sử T có nút gốc n có T1, ,Tn thì: • Biểu thức duyệt tiền tự T liệt kê nút n biểu thức duyệt tiền tự T1, T2, , Tn theo thứ tự • Biểu thức duyệt trung tự T biểu thức duyệt trung tự T1 nút n đến biểu thức duyệt trung tự T2, , Tn theo thứ tự • Biểu thức duyệt hậu tự T biểu thức duyệt hậu tự T1, T2, , Tn theo thứ tự đến nút n Ví dụ: cho hình I.3 Hình I.3: nhị phân Biểu thức duyệt tiền tự: A B C D E F H K L trung tự: C B E D F A K H L hậu tự: C E F D B K L H A Cây có nhãn biểu thức Ta thường lưu trữ kết hợp nhãn (label) gọi giá trị (value) với nút Như nhãn nút tên nút mà giá trị lưu giữ nút Nhãn nút đơi cịn gọi khóa nút, nhiên hai khái niệm không đồng Nhãn giá trị hay nội dung lưu trữ nút, khố nút phần nội dung lưu trữ Chẳng hạn, nút chứa record thông tin sinh viên (mã SV, họ tên, ngày sinh, địa chỉ, ) khố mã SV họ tên ngày sinh tuỳ theo giá trị ta quan tâm đến giải thuật Ví dụ: Cây biểu diễn biểu thức (a+b)*(a-c) hình I.4 Hình I.4: Cây biểu diễn thứ tự (a+b)*(a-c) - Ở n , n , , n tên nút *,+,-,a,b,c nhãn - Qui tắc biểu diễn biểu thức toán học sau: • Mỗi nút có nhãn biểu diễn cho tốn hạng • Mỗi nút trung gian biểu diễn tốn tử Hình I.5: Cây biểu diễn biểu thức E1 θ E2 - Giả sử nút n biểu diễn cho tốn tử hai ngơi θ ( chẳng hạn + * ), nút bên trái biểu diễn cho biểu thức E1, nút bên phải biểu diễn cho biểu thức E2 nút n biểu diễn biểu thức E1θ E2, xem hình I.5 Nếu θ phép tốn ngơi nút chứa phép tốn θ có nút con, nút biểu diễn cho toán hạng θ - Khi duyệt biểu diễn biểu thức toán học liệt kê nhãn nút theo thứ tự duyệt ta có: • Biểu thức dạng tiền tố (prefix) tương ứng với phép duyệt tiền tự • Biểu thức dạng trung tố (infix) tương ứng với phép duyệt trung tự • Biểu thức dạng hậu tố (posfix) tương ứng với phép duyệt hậu tự Ví dụ: hình I.4 ta có: - Biểu thức tiền tố: *+ab-ac - Biểu thức trung tố: a+b*a-c - Biểu thức hậu tố: ab+ac-* Chú ý - Các biểu thức khơng có dấu ngoặc - Các phép tốn biểu thức tốn học có tính giao hốn ta biểu diễn biểu thức phải tuân thủ theo biểu thức cho Ví dụ biểu thức a+b, với a,b hai số nguyên rõ ràng a+b=b+a hai biểu diễn cho hai biểu thức khác (vì có thứ tự) Hình I.6: Cây biểu diễn biểu thức a+b b+a - Chỉ có phía bên trái hình I.6 biểu diễn cho biểu thức a+b theo qui tắc - Nếu ta gặp dãy phép tốn có độ ưu tiên ta kết hợp từ trái sang phải Ví dụ a+b+c-d = ((a+b)+c)-d II Cây nhị phân (Binary Trees) Định nghĩa Cây nhị phân rỗng mà nút có tối đa hai nút Hơn nút phân biệt thứ tự rõ ràng, nút gọi nút trái nút gọi nút phải Ta qui ước vẽ nút trái bên trái nút cha nút phải bên phải nút cha, nút nối với nút cha đoạn thẳng Ví dụ hình I.7 Hình I.7: Hai có thứ tự giống hai nhị phân khác Chú ý rằng, nhị phân, nút nút trái nút phải, nên có có thứ tự giống hai nhị phân khác Ví dụ hình I.7 cho thấy hai có thứ tự giống hai nhị phân khác Nút nút trái a/ phải b/ Tương tự nút phải a/ trái b/ Vài tính chất nhị phân Gọi h n chiều cao số phần tử nhị phân Ta có tính chất sau: - Số nút mức i=log2(n+1) Biểu diễn nhị phân Ta chọn cấu trúc động để biểu diễn nhị phân: Trong đó: Lchild, Rchild trỏ đến nút bên trái nút bên phải Nó rỗng khơng có nút Nút có dạng Duyệt nhị phân Ta áp dụng phép duyệt tổng quát để duyệt nhị phân Tuy nhiên nhị phân cấu trúc đặc biệt nên phép duyệt nhị phân đơn giản Có ba cách duyệt nhị phân thường dùng (xem kết hợp với hình I.8): - Duyệt tiền tự (Node-Left-Right): duyệt nút gốc, duyệt tiền tự trái duyệt tiền tự phải - Duyệt trung tự (Left-Node-Right): duyệt trung tự trái đến nút gốc sau duyệt trung tự phải - Duyệt hậu tự (Left-Right-Node): duyệt hậu tự trái duyệt hậu tự phải sau nút gốc HìnhI.8 10 TKNP(a, x, +1, cuối); Else TKNP(a, x, đầu, giữa-1); } Độ phức tạp thuật toán Trường hợp tốt nhất: ứng với trường hợp tìm thấy x lần so sánh Ta có: Ttốt (n) = O(1) Trường hợp xấu nhất: độ phức tạp O(lgn) Thật vậy, gọi T(n) độ phức tạp thuật toán, sau kiểm tra điều kiện (x == a[giữa]) khơng thỏa gọi đệ quy thuật tốn với liệu giảm nửa, thỏa mãn công thức truy hồi: T(n) = 1+T(n/2); n>=2 T[1]=0 Bài tốn Min-Max Phát biểu tốn Tìm min-max đoạn a[l r] mảng a[1 n] Ý tưởng Tại bước chia đơi đoạn cần tìm tìm min, max đoạn, sau tổng hợp kết lại Nếu đoạn chia có phần tử = max phần tử Ví dụ minh họa: J a[j] 10 15 19 Tìm giá trị min, max đoạn a[2 7] Ki hiệu: MinMax(a,l,r,Min, Max) cho Min, Max đoạn a[l r] MinMax(a,2,7,Min,Max) cho Min=0, Max=15 đoạn a[2 7] Mô tả thuật toán Input: a[l r] (l