Cõy nhị phõn tỡm kiếm

Một phần của tài liệu Tài liệu hỗ trợ môn cấu trúc dữ liệu 2 (Trang 47)

Ch−ơng 3 Cõy đỏ đen

3.2.Cõy nhị phõn tỡm kiếm

Để cú thể thực hiện cỏc thao tỏc tỡm kiếm và chốn theo phơng phỏp nhị phõn trờn cõy nh ý t−ởng thiết kế chỳng ta nờu ra trờn đõy, chỳng ta phải tổ chức cõy nhị phõn theo một cỏch đỈc biƯt, sao cho khi thực hiện tỡm kiếm hoặc chốn ta luụn cú thể quyết định là hành động tiếp theo sẽ thực hiện ở cõy con trỏi hay cõy con phả

Thớ dơ chúng ta sẽ tỉ chức các nút sao cho tại mỗi nỳt bất kỳ các nút ở phía trái bao giờ cịng

khụng lớn hơn nỳt đú và tất cả cỏc nỳt phớa phải đều khụng bộ hơn nỳt đú. Cõy nhị phõn thỏa

mÃn tớnh chất này đ−ỵc gọi là cõy nhị phõn tỡm kiếm. Điều này cũng cho ta cỏch chốn một phần tử mới: bắt đầu từ gốc, ta sẽ lần tỡm vị trớ thớch hợp để chốn phần tử đú. Chúng ta có thĨ thấy rõ là hai cõy nhị phõn chứa cựng dữ liƯu có thĨ đ−ợc tổ chức hồn tồn khỏc nha Trong hình 3.1 nếu chúng ta chốn cỏc phần tử theo thứ tự đà sắp sẵn A,B,C,D,E ta sẽ đợc một cõy nhị phõn suy biến thành danh sỏch.

Hỡnh 3.1. Cõy nhị phõn suy biến

Trong tr−ờng hợp này mặc dự danh sỏch cú sắp thứ tự nhng việc tỡm kiếm hoặc chốn đều cần thời gian cú bậc tuyến tớnh. Cõy đ−ỵc tỉ chức kém nh− vậy đ−ợc gọi là khụng cõn bằng (unbalanced). Điều kiện hiển nhiờn để cõy nhị phõn đợc cõn bằng hoàn hảo là cõy cú số nỳt tối đa tại mỗi mức. Thớ dụ cõy trong hỡnh 3.3 là cõy nhị phõn hoàn hảo (cũn gọi là cõy nhị phõn đầy

đđ - complete binary tree):

Hỡnh 3.2. Cõy nhị phõn đầy đủ

Cõy nhị phõn đầy đủ luụn luụn cú số nỳt là 2d+1 -1, trong đó d là số mức của cõ Vậy để tạo cấu trỳc cõy nhị phõn đầy đủ thì tr−ớc hết dữ liệu ta khảo sỏt phải cú đúng 2d+1 -1 phần tư, trong đú d là số tự nhiờn. Rừ ràng điều kiện nh vậy là quỏ chặt trong thực tế. Tuy nhiên chúng ta cú thể thấy rằng cõy khụng cần phải cõn bằng đến mức hồn hảo nh− vậy; có những dạng cõn bằng nới lỏng hơn vẫn cho ta cấu trỳc dữ liệu hữu ớch và gần với thực tế. Trong cỏc phần sau chỳng ta sẽ định nghĩa một số dạng đặc biệt của cõ

A B C D E F G A B C D E

Cấu trúc dữ liƯu2 – Chơng 3. Cõy đỏ đen

Duyệt cõy nhị phõn

Cịng giống với một cấu trúc dữ liƯu bất kỳ, cỏc nỳt của cõy nhị phõn thờng chứa cỏc thụng tin và nhiỊu khi ta phải liệt kờ tất cả cỏc thụng tin đú theo một cỏch nào đú sao cho thụng tin mỗi nút chỉ đợc liệt kờ một lần và khụng cú nỳt nào bị bỏ sút. Để làm đợc việc này rừ ràng ta phải lần l−ợt thăm cỏc nỳt của cõy theo một thứ tự nào đú sao cho mỗi nút chỉ đ−ợc thăm đỳng một lần. Cỏch làm này gọi là phộp duyệt cõ Cú nhiều cỏch duyệt cõy, thớ dụ ta cú thể thăm cỏc nỳt theo từng mức lần l−ợt từ trỏi qua phả Tuy nhiờn nhiều khi phộp duyệt cõy khụng đơn thuần là liệt kờ thụng tin cỏc nỳt mà cũn nhằm một mục đớch khỏc. Vỡ vậy 4 phộp duyệt cõy sau đõy là đ−ỵc dùng nhiỊu nhất trong thực tế:

• Pretrav: dut cây theo thứ tự tr−ớc (NLR - Node Left Right) hay cũn đ−ỵc gọi là duyệt cõy theo độ sõ

Đầu tiờn chỳng ta thăm (visit) nỳt gốc.

Sau đú duyệt nhỏnh cõy con trỏi theo phộp duyệt pretrav. Cuối cựng duyệt nhỏnh cõy con phải theo phép dut pretrav.

• Intrav: duyệt cõy theo thứ tự giữa (LNR - Left Node Right) Duyệt nhỏnh cõy con trỏi theo phộp duyệt intrav.

Thăm (visit) nỳt gốc.

Cuối cựng duyệt nhỏnh cõy con phải theo phép dut intrav.

• Posttrav: dut cây theo thứ tự sau (LRN - Left Right Node) Dut nhánh cõy con trỏi theo phộp duyệt posttrav. Duyệt nhỏnh cõy con phải theo phộp duyệt posttrav. Thăm (visit) nỳt gốc.

• Breadthtrav: dut cây theo bề rộng tức là duyệt cõy theo mức Dut các nút từ trái qua phải, bắt đầu từ mức 0, mức 1, 2, ... Sau đõy là thứ tự cỏc nỳt trong cỏc phộp duyệt cõy nhị phõn ở hỡnh 3.3.

NLR: ABDEC LNR: DBEAC LRN: DEBCA Breadth: ABCDE Hình 3.3. Bốn phép dut cây nhị phõn 3.3. Cây 2-3-4

ĐĨ khư tr−ờng hỵp xấu nhất cho cõy nhị phõn tỡm kiếm, ta cần cú một vài linh động trong định nghĩa cấu trúc cây mớị Cơ thĨ ta cho phộp một nỳt trờn cõy cú thể chứa 1, 2 hoặc 3 khúa; và nh− vậy một nút có thĨ có tới 4 con. Ta sẽ mở rộng khỏi niệm cõy nhị phõn tỡm kiếm thành cõy 2-3- 4 nh− sau:

3.3.1. Định nghĩa cõy 2-3-4

Cõy 2-3-4 là cõy nhiều nhỏnh bậc 4 thỏa mãn các tính chất sau:

• Một nút bất kỳ trờn cõy phải có 1, 2 hc 3 khóa (nh− vậy khụng cú nỳt lỏ rỗng). Trừ nỳt lá

A

B C

http://www.ebook.edụvn

Cấu trúc dữ liƯu2 – Ch−ơng 3. Cõy đỏ đen

49 khụng cú con nào, cũn tất cả cỏc nỳt cũn lại đều cú đủ con, nghĩa là nếu nút có k (1 ≤ k ≤ 3) (adsbygoogle = window.adsbygoogle || []).push({});

khúa thỡ phải cú k+1 con.

Tất cả cỏc lỏ đều cựng nằm trờn một mức.

• Ngoài ra giỏ trị cỏc khúa trờn cõy 2-3-4 cần thoả mÃn cỏc điều kiện sau:

Cỏc khúa trờn mỗi nỳt đ−ỵc sắp xếp theo thứ tự tăng dần. Tại mỗi nỳt cỏc khúa trờn cõy

con bờn trỏi một khúa khụng lớn hơn khúa đú và cỏc khúa trờn cõy con bờn phải khụng bộ hơn khúa đú.

Hỡnh 3.4 sau mụ tả một cây 2-3-4:

Hình 3.4 Cây 2-3-4.

3.3.2. Tỡm kiếm trờn cõy 2-3-4

Giả sử chỳng ta cần tỡm nỳt có khóa x. Chúng ta xt phát từ gốc của cõy, và đi theo nhỏnh cõy thớch hợp. Giả sử ta đang ở đỉnh B. Nếu đỉnh B là lỏ thỡ ta phải tỡm trong nỳt B xem có khóa x hay khơng.

Nếu B là đỉnh trong chứa cỏc khúa k0, k1,..., kr r ∈ {0, 1, 2} thì ta cần xỏc định vị trớ của x trong dãy khóa nàỵ Thí dơ nếu x < k0 thì ta tìm x trờn cõy con nằm bờn trỏi k0, nếu ki-1< x < ki thỡ ta tỡm x trờn cõy con nằm giữa ki-1 và ki, còn nếu kr < x thỡ ta tỡm x trờn cõy con nằm bờn phải kr.

3.3.3. Thờm khúa vào cõy 2-3-4

Khi thêm một khóa x vào cõy thỡ chỳng ta phải ỏp dụng thủ tục tỡm kiếm để tỡm ra nỳt B cần phải xen và Nếu khúa x đà tồn tại trờn cõy thỡ ta khụng thờm nữa, vỡ cỏc khúa trờn cõy phải duy nhất, khụng đợc lặp lạ Ta cú thể thấy rằng thủ tục thờm nỳt luụn luụn có thĨ đ−ỵc thực hiƯn ở nỳt lỏ. Thật vậy, vỡ nỳt x ch−a cú trờn cõy nờn xuất phỏt từ nỳt gốc ta sẽ đi theo con đ−ờng đi qua cỏc nỳt trong để đến một nỳt lỏ nào đú. Tại một nỳt trung gian ta luụn cú hoặc là x < k0 trong đó k0 là khóa nhỏ nhất trong đỉnh đú, khi này ta đi theo nhỏnh cõy con nằm bờn trỏi khúa k0 . Nếu x > kr trong đó kr là khúa lớn nhất trong nỳt đú, khi này ta đi theo nhỏnh cõy con nằm bờn phải khúa kr. Nếu ki-1< x < ki thỡ ta đi theo cõy con nằm giữa ki-1 và ki. Vậy thao tỏc thờm nỳt luụn đợc thực hiện ở một nỳt lỏ nào đú đợc xỏc định bởi x. Giả sử ta đến nút lá B. Ta thực hiƯn viƯc chèn nút x nh− sau:

• Nếu nút lá B ch−a đầy thỡ chỳng ta chốn khúa x vào nỳt này theo thao tỏc chốn nỳt vào danh sỏch sắp thứ tự.

• Nếu nỳt B đà đầy, tức là cú 3 khúa, nếu ta thờm khúa x thỡ nỳt B bị tràn. Giả sư cùng với x ta có các khóa mới trong nút B là k0’, k1’, k2’, k3’, Ta tách nút B thành 2 nút, nút đầu cú cỏc khúa k0’, k1’ nút thứ 2 B chứa 1 khoỏ là k3’ cịn khóa k2’ sẽ đ−ợc chốn vào nút cha cđa B cùng với nút B là con bờn phả Nếu nỳt cha bị đầy ta lại thực hiện t−ơng

20 40 5 10 30 45 55 65 70 2 4 15 25 35 42 47 49 52 60 63 68 72 95 75 85 50 7 78

Cấu trúc dữ liƯu2 – Ch−ơng 3. Cõy đỏ đen

tự nh− với nút B. Nh− vậy viƯc tách nút có thĨ lan trun tới gốc và nỳt gốc cú thể bị tỏch làm 2 và gốc mới đợc tạo r Đõy chớnh là cỏch duy nhất để cõy 2-3-4 cú thể tăng chiều cao: nú lớn lờn từ lỏ đến gốc.

Vớ dụ: Xột cõy 2-3-4 sau đõy:

Hình 3.5 Thêm khóa 22 vào

cây 2-3-4

1. Giả sư ta phải thờm khúa 22 vào cõ Nỳt A khụng cú khúa 22 và ta tiếp tục tỡm kiếm trên nút C. Nỳt C là nỳt lỏ cuối cựng trờn đờng tìm kiếm khóa 22, do vậy ta sẽ thực hiƯn viƯc chèn khúa 22 ở đõ

2. Tuy nhiờn nỳt C đà đầy, do đú ta tỏch nỳt C thành 2 nỳt và ta cú thờm nỳt mới là D. 3. Khóa 30 đ−ợc chuyển lờn nỳt ch Đồng thời ta đặt mối liờn kết từ nỳt cha xuống nút D.

3.3.4. Loại bỏ khóa trờn cõy 2-3-4

Về nguyờn tắc, việc loại bỏ nỳt trờn cõy hoàn toàn đơn giản nhng phức tạp trong chi tiết thực hiện. Để loại bỏ một khúa x, tr−ớc hết ta tỡm kiếm trờn cõy để xỏc định vị trớ của khúa x. Việc tiến hành loại bỏ dĩ nhiờn chỉ đ−ợc thực hiện khi thao tỏc tỡm kiếm cú kết quả. Cú 2 tỡnh huống sau:

(1) Phần tư cần loại bỏ ở nỳt lỏ: việc loại bỏ phần tử này đợc thực hiện khỏ dễ dàng nh− loại bỏ phần tử trờn danh sỏch.

(2) Phần tử cần loại bỏ nằm ở nỳt trung gian. Lỳc này ta khụng thể loại bỏ trực tiếp phần tử trờn nỳt này, vỡ phần tử này cũn cú cỏc cõy con liờn quan. Ta phải tỡm một phần tử khỏc nằm ở nỳt lỏ làm phần tử thay thế, nghĩa là giỏ trị khúa của phần tử thay thế sẽ đ−ợc gỏn cho giỏ trị khúa của phần tử cần xúa, sau đú phần tư thay thế đ−ợc loại bỏ khỏi nỳt lỏ chứa nó. Ta thấy phần tư thay thế phải là phần tử cực phải của nhỏnh cõy con trỏi hoặc nỳt cực trỏi của nhỏnh cõy con phải của phần tử cần xóạ Chúng ta sẽ quy −ớc chọn phần tư cần thay thế là phần tử cực phải trờn nhỏnh cõy con trỏ

Vậy trong mọi trờng hợp ta đều đ−a về tr−ờng hợp xúa khúa trờn nỳt lỏ. Nh− vậy ta chỉ cần nghiờn cứu tr−ờng hợp này:

Giả sử nỳt lỏ cú khúa cần xúa là nỳt Z. Ta xét 2 tr−ờng hỵp sau:

(a) Nút Z có nhiỊu hơn 1 khú Lỳc này ta chỉ cần xúa khúa x trờn Z và kết thúc.

(b) Nếu Z chỉ cú một khúa x. Giả sử nỳt cha là F và nút Z có nút lỏng giềng (cựng mức) bờn trỏi là L. Giả sử khúa f trong nút F là khóa cha cđa nút L và Z. Lúc này sau khi xóa x nút Z thành rỗng và do đú khúa f khụng cú con phả Ta đ−a khúa f xuống nỳt L. ở đõy ta lại gặp 2 tình huống: 20 7 10 15 26 30 35 20 30 7 10 15 22 26 35 A B C A B C D (adsbygoogle = window.adsbygoogle || []).push({});

http://www.ebook.edụvn

Cấu trúc dữ liƯu2 – Chơng 3. Cõy đỏ đen

51 - Nếu nút L ch−a đầy thỡ ta phải cõn bằng lại nỳt F, quỏ trỡnh cõn bằng cú thể lan truyền

đến gốc và cú thể nỳt gốc bị loại bỏ: cõy đà thấp xuống. Đõy chớnh là cỏch duy nhất để cõy 2-3-4 giảm chiỊu caọ

- Nếu nút L đầy thỡ sẽ đợc tỏch làm hai và có một nút đ−ợc chốn vào nỳt F thay thế khóa f. Thực chất khúa này chớnh là khúa cực phải của L khi ch−a đ−a nút cha xng, cịn khóa f sẽ là khúa của nỳt đợc tỏch r

Ví dụ: Ta xột cõy sau đõy:

Hình 3.6. Xóa khóa 32 trờn cõy 2-3-4 Giả sư ta cần xóa khóa 32. Nút chứa khóa 32 khụng phải nỳt lỏ, vỡ vậy ta phải tỡm một khóa thay thế. Theo quy −ớc, nỳt cực phải trờn cõy con trỏi của khúa 32 là khúa 30. Ta đ−a giỏ trị khúa 30 vỊ vị trí cđa khóa 32 rồi xóa khóa 30 trờn nỳt lỏ chứa nú và nhận đ−ỵc cây mới nh− sau:

Hình 3.7. Cây sau khi xóa khóa 32 Ta nhận thấy nút F ở trong tỡnh trạng cạn kiệt. Ta sẽ xúa nút F, đồng thời chun khóa 26 xng nút Ẹ Ta đợc kết quả sau Hình 3.8. Cân bằng lại nút F 30 20 26 38 44 B 7 10 15 22 24 34 36 40 42 46 48 A C F D E I J K 32 20 26 38 44 B 7 10 15 22 24 30 34 36 40 42 46 48 A C F D E I J K 30 20 38 44 B 7 10 15 34 36 40 42 46 48 A C F D E I J K 22 24 26

Cấu trúc dữ liƯu2 – Ch−ơng 3. Cõy đỏ đen

Bõy giờ cõy đà cõn bằng.

3.3.5. Phõn tớch cỏc thuật toỏn trờn cây 2-3-4

Cũng nh− cõy nhị phõn tỡm kiếm, khi chốn một khúa x vào cõy hay tìm kiếm một khóa x trong cõy, ta xuất phỏt từ gốc và luụn đi theo đờng cha - con (tức là khơng có tr−ờng hợp nào ta duyệt nhiều hơn một cõy con của một nỳt nào đú). Nếu là thao tỏc chốn thỡ ta luôn luôn dừng ở một nút lá. Trong tr−ờng hợp này nếu độ cao của cõy là h thỡ ta phải duyệt qua h+1 nút (vì nút gốc đ−ỵc quy −ớc là cú độ cao 0). Bài toỏn đặt ra là: giả sử cõy cú n khúa, khi đú ta phải duyệt qua bao nhiêu nút trong tr−ờng hỵp xấu nhất? Bài toỏn này cũng tơng đơng với bài tốn sau: cho n khóa, hÃy xỏc định chiều cao lớn nhất của của cõy 2-3-4 tạo từ n khúa nà Ta thấy rằng cây cao nhất là cõy cú số khúa tối thiểu trong mỗi nút. Xét tr−ờng hợp n nhận một giỏ trị thớch hợp, ta thấy rằng số khúa tối thiểu trờn mỗi nỳt là một, do đú số con của một nỳt là 2. Nh− vậy ta thấy rằng mức 0 có 1 nút, mức 1 có 2 = 21, ... mức i có 2i nút. Và nh− vậy cây có chiỊu cao h sẽ có 1+2 + 22 +... +2h = 2h+1 - 1 nỳt. Tuy nhiờn vỡ mỗi nỳt chỉ chứa một khóa nên tỉng số nút cịng là tỉng số khóạ Nh− vậy ta có hệ thức 2h+1 - 1. Kết quả này thực ra có thĨ suy ra dƠ dàng, vỡ cõy 2-3-4 mà mỗi nỳt chỉ cú một khúa chớnh là cõy nhị đầy đủ hay là cõy nhị phõn cõn bằng hoàn toàn. Nh− vậy số nút cần dut nhiỊu nhất trong quỏ trỡnh chốn khúa là h+1 = log2(n+1). Ta hãy xét tr−ờng hợp tốt nhất mà cõy 2-3-4 cú thể đạt tới: cõy cú chiều cao thấp nhất trong cỏc cõy 2-3-4 cú n nút. Ta thấy rằng cây thấp nhất khi tất cả cỏc nỳt chứa tối đa số khóạ Lúc này tỉng số nỳt trong cõy là: mức 0 cú 1, mức 1 có 4, ..., mức i có 4i nút. Nh− vậy cây chiỊu cao h có 1+ 4 + 42 + ... + 4h = 1 4 1 4 1 − − + h = 3 1 4h+1 − nút

Vỡ mỗi nỳt chứa 3 khúa nờn tổng số khoỏ là n =

3 1 4h+1 −

* 3 = 4h+1 -1. Từ đõy ta cú h+1 = log4(n+1). Tuy nhiên có thể thấy rằng trờn mỗi nỳt ta phải so sỏnh với 3 khúa, nờn nếu gọi k là số phép so sỏnh trung bỡnh cần thực hiện trờn mỗi nỳt, và gọi tổng số phộp so sỏnh là p, ta có k*log4(n+1) ≤ p ≤ log2(n+1). Nói chung ta ln ln có: log4(n+1) ≤ p ≤ log2(n+1). Từ đõy ta có thĨ kết ln là phộp chốn và phộp tỡm kiếm trờn cõy 2-3-4 chứa n khúa khụng bao giờ

dut nhiỊu hơn log2(n+1) nút. Vậy cỏc phộp toỏn này cú độ phức tạp tớnh toỏn là log2n.

Có thể thấy rằng việc cài đặt cõy 2-3-4 với cỏc thao tỏc tỡm kiếm hay chốn, xúa khụng khú

Một phần của tài liệu Tài liệu hỗ trợ môn cấu trúc dữ liệu 2 (Trang 47)