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

Một phần của tài liệu 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 hoàn toà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ự nh−ng 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 hoà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

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 đó dut 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) Dut 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) Duyệt nhỏnh cõy con trái theo phép dut 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 Duyệt 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 duyệt 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)

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.

• Ngồ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 cha đầ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

tự nh− với nút B. Nh− vậy việc tỏch nỳt cú thể lan truyền 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 xng 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 nh−ng 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

http://www.ebook.edụvn

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

51 - Nếu nút L cha đầ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 chuyển 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

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 toỏ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 Cấu trúc dữ liệu 2 (Trang 47)

Tải bản đầy đủ (PDF)

(116 trang)