Cây và các khái niệm về cây
Chơng Trong chơng nghiên cứu mô hình liệu Cây cấu trúc phân cấp tập hợp đối tợng Một ví dụ quen thuộc cây, th mục Cây đợc sử dụng rộng rÃi nhiều vấn đề khác Chẳng hạn, đợc áp dụng để tổ chức thông tin hệ sở liệu, để mô tả cấu trúc cú pháp chơng trình nguồn xây dựng chơng trình dịch Rất nhiều toán mà ta gặp lĩnh vực khác đợc quy việc thực phép toán Trong chơng trình bày định nghĩa khái niệm Chúng ta xét phơng pháp cài đặt thực phép toán Sau nghiên cứu kỹ dạng đặc biệt, tìm kiếm nhị phân 4.1 Cây khái niệm Hình 4.1 minh hoạ T Đó tập hợp T gåm 11 phÇn tư, T={a, b, c, d, e, f, g, h, i, j, k} Các phần tử T đợc gọi đỉnh T Tập T có cấu trúc nh sau Các đỉnh T đợc phân thành lớp không cắt : lớp thứ gồm đỉnh a, đỉnh gọi gốc cây; lớp thứ hai gồm đỉnh b, c ; lớp thứ ba gồm đỉnh d, e, f, g, h lớp cuối gồm đỉnh i, j, k, đỉnh thuộc lớp (trừ gèc), cã mét cung nhÊt nèi víi mét ®Ønh thuộc lớp kề (Cung biểu diễn mối quan hệ đó) a b d c e i f j g h k H×nh 4.1 BiĨu diƠn hình học Trong toán học có nhiều cách định nghĩa đa định nghĩa đệ quy Định nghĩa cho phép ta xuất phát từ đơn giản ( có đỉnh) xây dựng nên lớn Cây (cây có gốc) đợc xác định đệ quy nh sau Tập hợp gồm đỉnh Cây có gốc đỉnh nã Gi¶ sư T1, T2, , Tk (k ũ 1) có gốc tơng ứng r1,r2 ,rk Các Ti (i = 1, 2, k) , không không cắt tức Ti ù Tj = f với i j Giả sử r đỉnh không thuộc Ti (i = 1, 2, , k) Khi đó, tập 76 hợp T gồm đỉnh r tất đỉnh c©y T i (i = 1, 2, , k) lập thành với gốc r Các Ti (i = 1, 2, , k) đợc gọi gốc r Trong biểu diễn hình học T, đỉnh ri (i =1, 2, ,k) cã cung nèi víi gèc r (xem h×nh 4.2) r r1 r2 rk T1 T2 Tk H×nh 4.2 Cây có gốc r gốc T1, T2, , Tk Cha, con, ®êng ®i Tõ định nghĩa ta suy rằng, đỉnh gốc của Số đỉnh gọi bậc đỉnh Các đỉnh có bậc không đợc gọi Nếu đỉnh b gốc đỉnh a ta nói đỉnh b đỉnh a a cha b Nh vậy, bậc đỉnh số đỉnh nó, đỉnh Các đỉnh có đợc gọi đỉnh Các đỉnh là đỉnh Các đỉnh có cha đợc gọi anh em Một dÃy đỉnh a 1, a2, an (n ³ 1), cho (i = 1, 2, , n-1) lµ cha cđa a i+1 đợc gọi đờng từ a1 đến an Độ dài đờng n-1 Ta có nhận xét rằng, luôn tồn đờng ®i nhÊt tõ gèc tíi mét ®Ønh bÊt kú Nếu có đờng từ đỉnh a đến đỉnh b có độ dài k 1, ta nói a tiền thân b b hậu a Ví dụ Trong hình 4.1, đỉnh c cha đỉnh f, g, h Các đỉnh d, i, j, k h lá, đỉnh lại đỉnh a, c, g, k đờng có độ dài từ a đến k Đỉnh b tiền thân đỉnh d, e, i, j Cây Từ định nghĩa ta có, đỉnh a T gốc đó, ta gọi T Nó gồm đỉnh a tất đỉnh hậu a Chẳng hạn, với T hình 4.1, T = {c, f, g, h, k} lµ mét Độ cao, mức Trong cây, độ cao đỉnh a độ dài đờng dài từ a đến Độ cao gốc đợc gọi độ cao Mức ®Ønh a lµ ®é dµi cđa ®êng ®i tõ gèc ®Õn a Nh vËy gèc cã møc VÝ dô Trong hình 4.1, đỉnh b có dộ cao 2, có độ cao Các đỉnh b, c có mức ; đỉnh d, e, f, g, h có mức 2, mức đỉnh i, j, k 77 Cây đợc Trong cây, đỉnh đợc theo thứ tự định, đợc gọi đợc Chẳng hạn, hình 4.3 minh hoạ hai đợc khác nhau, a a b c c b Hình 4.3 Hai đợc khác Sau quan tâm đến đợc Do nói đến cần đợc hiểu đợc Giả sử đợc T, đỉnh a có đợc theo thứ tự : b1, b2, , bk (k ³ 1) Khi ®ã ta nãi b1 lµ trëng cđa a, vµ bi lµ anh liỊn kỊ cđa bi+1 (bi+1 lµ em liỊn kỊ cđa bi), i = 1,2, , k-1 Ta cßn nãi, víi i < j b i bên trái bj (bj bên phải bi) Quan hệ đợc mở rộng nh sau Nếu a bên trái b hậu a bên trái hậu b Ví dụ Trong hình 4.1, f trởng c, anh liền kề đỉnh g Đỉnh i bên trái đỉnh g Cây gắn nhÃn Cây gắn nhÃn mà đỉnh đợc gắn với giá trị (nhÃn) Nói cách khác, gắn nhÃn với ánh xạ từ tập hợp đỉnh vào tập hợp giá trị (các nhÃn) Chúng ta xem nhÃn nh thông tin liên kết với đỉnh NhÃn liệu đơn nh số nguyên, số thực, liệu phức tạp nh ghi Cần biết rằng, đỉnh khác cđa c©y cã thĨ cã cïng mét nh·n Rõng Một rừng F danh sách : F = (T1, T2, , Tn) ®ã Ti(i = 1, , n) (cây đợc sắp) Chúng ta có tơng ứng - tập hợp tập hợp rừng Thật vậy, T với gốc r gốc theo thứ tự từ trái sang phải T1, T2, , Tn, T = (r, T1, T2, , Tn) t¬ng øng víi rõng F = (T1, T2, , Tn) vµ ngợc lại 4.2 Các phép toán Trong mục đà trình bày cấu trúc toán học Để có mô hình liệu cây, ta cần phải xác định phép toán thực đợc Cũng nh với danh sách, phép toán thực đợc 78 đa dạng phong phú Trong số đó, có số phép toán đợc sử dụng thờng xuyên để thực phép toán khác thiết kế thuật toán 2.1 Các phép toán Tìm cha đỉnh Giả sử x đỉnh T Hàm Parent(x) xác định cha đỉnh x Trong trờng hợp đỉnh x cha (x gốc) giá trị hàm Parent (x) ký hiệu đặc biệt khác với tất đỉnh cây, chẳng hạn $ Nh parent (x) = $ x gốc Tìm bên trái (con truởng) ®Ønh Hµm EldestChild (x) cho ta trëng cđa ®Ønh x Trong trờng hợp x (x con) th× EldestChild (x) = $ T×m em liỊn kể đỉnh Hàm NextSibling (x) xác định em liền kề đỉnh x Trong trờng hợp x không cã em liỊn kỊ (tøc x lµ ngoµi cïng bên phải đỉnh đó) NextSibling(x) = $ Ví dụ Giả sử T đà cho hình 4.1 Khi Parent(e) = b, Parent(a) = $, EldestChild (c) = f, EldestChild (k) = $, NextSibling (g) = h, NextSibling (h) = $ 4.2.2 §i qua (duyệt cây) Trong thực tiễn gặp nhiều toán mà việc giải đợc qui việc qua (còn gọi duyệt cây), "thăm" tất đỉnh cách hệ thống Có nhiều phơng pháp qua Chẳng hạn, ta qua lần lợt từ mức 0, møc 1, cho tíi møc thÊp nhÊt Trong mức ta thăm đỉnh từ trái sang phải Ví dụ, với hình 4.1, danh sách đỉnh lần lợt đợc thăm (a, b, c, d, e, f, g,h, i, j, k) Đó phơng pháp qua theo bề rộng Tuy nhiên, ba phơng pháp qua theo hệ thống sau quan trọng : qua theo thứ tự Preorder, Inorder Postorder Danh sách đỉnh theo thứ tự Preordor, Inorder, Postorder (gọi tắt danh sách Preorder, Inorder, Postorder) đợc xác định đệ qui nh sau : Nếu T gồm đỉnh danh sách Preordor, Inorder Postorder chứa đỉnh Nếu T có gốc r gốc T1, T2, , Tk (hình 4.2) 2a Danh sách Preorder đỉnh T bắt đầu r, theo sau đỉnh T1 theo thứ tự Preordor, đến đỉnh T theo thứ tự Preorder, , cuối đỉnh Tk theo thø tù Preordor 2b Danh s¸ch Inorder c¸c đỉnh T bắt đầu đỉnh T1 theo thứ tự Inordor, đến gốc r, theo sau đỉnh T2, Tk theo thø tù Inordor 2c Danh s¸ch Postorder đỉnh T lần lợt đỉnh T1, T2, Tk, theo thứ tù Postorder sau cïng lµ gèc r 79 VÝ dơ, qua hình 4.1 theo thứ tự Preordor ta đợc danh sách đỉnh (a, b, d, e, i, j, c, f, g, k, h) NÕu ®i qua c©y theo thø tù Inorder, ta cã danh s¸ch (d, b, i, e, j, a, f, c, k, g, h) Còn danh sách Postorder (d, i, j, e, b, f, k, g, h, c, a) Phơng pháp qua theo thứ tự Preorder đợc gọi kỹ thuật qua theo độ sâu Đó kỹ thuật quan trọng thờng đợc áp dụng để tìm kiếm nghiệm toán Gọi qua theo độ sâu, ta đỉnh x (chẳng hạn, đỉnh b hình 4.1), ta cố gắng sâu xuống đỉnh cha đợc thăm bên trái chừng đợc (chẳng hạn, đỉnh d hình 4.1) để thăm đỉnh Nếu tất đỉnh x đà đợc thăm (tức từ x sâu xuống đợc) ta quay lên tìm đến cha x Tại ta lại cố gắng sâu xuống đỉnh cha đợc thăm Chẳng hạn, hình 4.1, ta đỉnh f, sâu xuống, ta quay lên cha f đỉnh c Tại c sâu xuống thăm đỉnh g, từ g lại sâu xuống thăm đỉnh k Quá trình tiếp tục toàn đỉnh đà đợc thăm Đối lập với kỹ thuật qua theo độ sâu kỹ thuật qua theo bề rộng mà đà trình bày Trong kỹ thuật này, thăm đỉnh x cây, ta theo bề ngang sang bên phải tìm đến em liền kề x để thăm Nếu x đỉnh bên phải, ta xuống mức sau thăm đỉnh bên trái, lại tiếp tục theo bề ngang sang bên phải Sau trình bày thủ tục qua theo thứ tự Preorder, Inorder, Postorder qua theo bề rộng Sử dụng phép toán định nghĩa đệ qui thứ tự Preorder, dễ dàng viết đợc thủ tục đệ qui qua theo thứ tự Preorder Trong thđ tơc, chóng ta sÏ sư dơng thđ tục Visit (x) (thăm đỉnh x) đợc cài đặt t theo tõng øng dơng C¸c biÕn A, B thủ tục đỉnh (Node) procedure Preorder ( A : Node) ; {Thđ tơc ®Ư qui ®i qua c©y gèc A theo thø tù Preorder} var B : Node begin Visit (A) ; B : = EldestChild (A) while B < > $ begin Preorder ( B) ; B : = NexSibling (B) end ; end ; Một cách tơng tự, ta viết đợc thủ tục đệ qui qua theo thứ tù Inorder vµ Postorder procedure Inorder ( A : Node) ; {Thủ tục đệ qui qua gốc A theo thø tù Inorder } 80 var B : Node ; begin B := EldestChild (A) ; if B < > $ then begin Inorder (B) : B : = NextSibling (B) end ; Visit (A) ; while B < > $ begin Inorder (B) ; B : = NextSibling (B) end ; end ; procedure Postorder (A : Node) ; {Thủ tục đệ qui qua gốc A theo thø tù Postorder} var B : Node ; begin B : = EldestChild (A) ; while B < > $ begin Postorder (B) ; B : = NextSibling (B) end ; Visit (A) end ; Chóng ta viết đợc thủ tục không đệ qui qua theo thứ tự Preordor, Inorder vµ Postorder Chóng ta sÏ viÕt mét ba thđ tục (các thủ tục khác giành lại cho độc giả) T tởng thuật toán không đệ qui qua theo thứ tự Preorder nh sau Chóng ta sÏ sư dơng mét stack S ®Ĩ lu giữ đỉnh Nếu thời điểm ta thăm đỉnh x stack lu giữ đờng từ gốc đến x, gốc đáy stack x đỉnh stack Chẳng hạn, với hình 4.1, ta thăm đỉnh i, stack lu (a, b, e, i) i đỉnh stack procedure Preorder ( A : Node) ; {Thủ tục không đệ qui qua c©y theo thø tù Preorder} var B : Node ; S : Stack ; begin Intealize (S) ; {khëi tạo stack rỗng} B:=A; 81 while B < > $ begin Visit (B) ; Push (B, S) ; {®Èy B vµo stack} B : = EldestChild (B) end ; while not Empty (S) begin Pop (S,B) ;{loại phần tử đỉnh stack gán cho B] B : = NexSibling (B) ; if B < > $ then while B < > $ begin Visit (B) ; Push (B, S) ; B : = EldestChild (B) end ; end ; end ; Sau trình bày thuật toán qua theo bề rộng, sử dụng hàng Q để lu giữ đỉnh theo thứ tự đà đợc thăm, đầu hàng đỉnh bên trái mà ta cha thăm nó, cuối hàng đỉnh ta thăm Chẳng hạn, với hình 4.1, ta thăm đỉnh i hàng chứa đỉnh (f, g, h, i) f đầu hàng i cuối hàng Khi loại phần tử đầu hàng, lần lợt thăm (nếu có) thăm đỉnh đa đỉnh vào cuối hµng Chóng ta cã thđ tơc sau procedure BreadthTraverse ( A : Node) ; {Thủ tục qua gốc A theo bÒ réng } var B : node ; Q : Queue ; begin Initialize (Q) ; {khëi t¹o hàng rỗng} Visit (A) ; Add (A, Q) ; {đa gèc A vµo hµng Q} while not Empty (Q) begin 82 Delete (Q, B) ; {loại phần tử đầu hàng gán cho B} B : = EldestChild (B) ; while B < > $ begin Visit (B) ; Add (B, Q) ; B : = NextSibling (B) end ; end ; end ; 4.3 Cài đặt Trong mục trình bày phơng pháp cài đặt nghiên cứu khả thực phép toán cách cài đặt 4.3.1 Biểu diễn danh sách đỉnh Phơng pháp thông dụng để biểu diễn là, với đỉnh ta thành lập danh sách đỉnh theo thứ tự từ trái sang phải Cài đặt mảng Trong cách cài đặt này, ta sử dụng mảng để lu giữ đỉnh Mỗi thành phần mảng tế bào chứa thông tin gắn với đỉnh danh sách đỉnh Danh sách đỉnh đỉnh biểu diễn mảng danh sách liên kết Tuy nhiên, số đỉnh thay đổi nhiều, ta sử dụng danh sách liên kết Nh tế bào mô tả đỉnh mét b¶n ghi gåm hai trêng : trêng infor chøa thông tin gắn với đỉnh, trờng Child trỏ tới danh sách đỉnh Giả sử đỉnh đợc đánh số từ đến N với cách cài đặt này, ta khai báo cấu trúc liệu biểu diễn nh sau : const N = ; { N lµ sè lớn đỉnh mà có } type pointer = ^ Member : Member = record id : N ; next : pointer end ; Node = record infor : item ; child : pointer end ; Tree = array [1 N] of Node ; 83 Trong khai báo trên, Member biểu diễn thành phần danh sách con, Node biểu diễn đỉnh Với cách cài đặt này, cấu trúc liệu biểu diễn hình 4.4a đợc minh hoạ hình 4.4b Ta có nhận xét rằng, cách cài đặt này, với đỉnh k ta xác định trởng Chẳng hạn, với hình 4.4b, trởng đỉnh đỉnh 6, trởng đỉnh 9, đỉnh Phép toán tìm trởng EldestChild (k) đợc mô tả hàm sau function EldestChild ( k : N ; T : Tree) : N ; var P : pointer ; begin if T[k] < > nil then begin P : = T[k] child ; EldestChild : = P^ id ; end else EldestChild : = end ; Tuy nhiªn cách cài đặt này, việc tìm cha em liền kề đỉnh lại không đơn giản Chẳng hạn, để tìm cha đỉnh k, ta phải duyệt danh sách đỉnh Nếu phát danh sách đỉnh m có chứa k Parent (k) = m Hàm Parent (k) đợc xác định nh sau : function Parent (k : N ; T : Tree) : N ; var P : pointer ; i : N ; found : boolean ; begin i:=1; found : = false ; while ( i < = N) and (not found) begin P : = T[i].child ; while (P < > nil) and (not found) if P^.id = k then begin Parent : = i : found : = true ; end else P : = P^.next ; i: = i + 84 end ; if not found then Parent : = ; end ; Một cách tơng tự (duyệt danh sách con), ta tìm đợc em liền kề đỉnh Mô tả chi tiết hàm NextSibling đợc để lại xem nh tập A B D E I 9 10 11 C infor child A B C D • E F • G H • I • K • M • F K 10 id G H M 11 (a) next • • 10 • 11 • • (b) H×nh 4.4 CÊu tróc liệu biểu diễn Cài đặt trỏ Nếu không dùng mảng để lu giữ đỉnh cây, ta sử dụng trỏ trỏ tới đỉnh Tại đỉnh, ta sÏ sư dơng mét danh s¸ch c¸c trá trá tới nó, danh sách đợc cài đặt mảng trỏ Một trỏ Root đợc sử dụng để trỏ tới gốc Ta khai báo cấu trúc liệu biểu diễn cách cài đặt nh sau const K = ; {K số tối đa đỉnh} 85 ... trái, T bên phải gốc Cây nhị phân T đợc biểu diễn hình 4.9 r T1 T2 Hình 4.9 Cây nhị phân có gốc r, trái T1, phải T2 Cần lu ý rằng, (cây có gốc) nhị phân hai khái niệm khác Cây không trống, luôn... đỉnh g Đỉnh i bên trái đỉnh g Cây gắn nhÃn Cây gắn nhÃn mà đỉnh đợc gắn với giá trị (nhÃn) Nói cách khác, gắn nhÃn với ánh xạ từ tập hợp đỉnh vào tập hợp giá trị (các nhÃn) Chúng ta xem nhÃn nh... đỉnh gọi bậc đỉnh Các đỉnh có bậc không đợc gọi Nếu đỉnh b gốc đỉnh a ta nói đỉnh b đỉnh a a cha b Nh vậy, bậc đỉnh số đỉnh nó, đỉnh Các đỉnh có đợc gọi đỉnh Các đỉnh là đỉnh Các đỉnh có cha đợc