CÂY CÂN BẰNG (AVL)

Một phần của tài liệu giáo trình toán rời rạc phần 2 (Trang 62 - 65)

Cây AVL được gọi theo tên của hai người đề xuất chúng là G.M. Adelson- Velsky và E.M. Landis được công bố vào năm 1962. Cây AVL thường được so sánh với cây đỏ đen vì chúng hỗ trợ các phép toán như nhau và cùng tốn thời gian O(logn) cho các phép toán cơ sở.

5.6.1. Định nghĩa

Cây cân bằng AVL là một cây tìm kiếm nhị phân mà tại mỗi nút chiều cao của hai cây con sai khác nhau không quá một. Hiệu số giữa chiều cao của cây con trái và cây con phải của nó được gọi là hệ số cân bằng của cây. Nếu hệ số bằng 0 thì cây được gọi là cân bằng hoàn toàn.

5.6.2. Tính hệ số cân bằng và chiều cao của cây

Với một cây con T gốc u, khi nút u là nút lá thì chiều cao của u bằng 0. Với mỗi nút u không là nút lá chiều cao của u bằng giá trị lớn nhất của chiều cao của nút con trái và chiều cao của nút con phải cộng thêm 1.

Ta gọi B(u) là hệ số cân bằng tại nút u và H(u) là chiều cao của cây có gốc u.

Dựa vào nhận xét trên ta xây dựng thủ tục tính chiều cao và hệ số cân bằng cây con T gốc u sau

Procedure Balance(uT);

Begin

if (u.left=nil) and (u.right=nil) then begin

H(u):=0; B(u):=0;

end else

if (u.left=nil) and (u.right<>nil) then begin H(u):=H(u.right)+1; B(u):=H(u);

end else

if (u.left<>nil) and (u.right=nil) then begin

H(u):=H(u.left)+1; B(u):=H(u);

end else

End;

begin

H(u):=max(H(u.left), H(u.right))+1;

B(u):=H(u.left)- H(u.right);

end;

5.6.3. Các phép toán trên cây AVL Phép chèn (Insertion)

Giả sử T là cây AVL và u là một nút của T và x là nút mới được chèn

vào u. Do x chỉ có thể được chèn vào đúng một trong hai cây con của u nên nhiều nhất x có thể làm tăng chiều cao của một trong hai cây con đó. Nếu x không làm tăng chiều cao của cây con nào hoặc x làm tăng chiều cao của một cây con nhưng trước đó chiều cao của cây con này có chiều cao nhỏ hơn hoặc bằng chiều cao của cây con kia thì tính cân bằng AVL tại nút u vẫn không đổi. Tính cân bằng của nút u chỉ thay đổi khi x làm tăng chiều cao của cây con có chiều cao lớn hơn trong hai cây con của u.

Nút x được thêm vào với tư cách là con của của một nút trước đó là lá hoặc nửa lá. Nếu cha của x trước khi thêm x vào là nửa lá thì chiều cao của cây con gốc cha của x không thay đổi và hệ số cân bằng tại nút này bằng 0 sau khi nút x được thêm vào.

Tính cân bằng của cây T được giữ nguyên

Nếu nút cha của x là nút lá, gọi u là tiền bối của x có mức cao nhất mà tính cân bằng bị phá vỡ. Sẽ có những khả năng sau

(1). Trước khi chèn cây con gốc u lệch trái và x làm tăng chiều cao của cây con trái.

(1.1). Sau khi chèn cây con trái lệch trái (LL) (1.2). Sau khi chèn cây con trái lệch phải (LR)

(2). Trước khi chèn cây con gốc u lệch phải và x làm tăng chiều cao của cây con phải.

(2.1). Sau khi chèn cây con phải lệch phải (RR)

(2.2). Sau khi chèn cây con phải lệch trái (RL) Trường hợp 1(LL): Thực hiện phép quay phải tại u

rotate_right(u);

Trường hợp 2(LR): Thực hiện phép quay trái tại nút u trái sau đó thực hiện phép quay phải tại u

rotate_left(u.left); rotate_right(u);

Trường hợp 3(RR): Thực hiện phép quay trái tại u rotate_left(u);

Trường hợp 4(RL): Thực hiện phép quay phải tại nút u phải sau đó thực hiện phép quay trái tại u

rotate_right(u.right); rotate_left(u);

Phép xóa (Deletion)

Giả sử phải xóa nút v trên cây AVL. Trước hết thực hiện phép xóa như với cây tìm kiếm nhị phân thông thường. Khi đó v luôn được thay bằng một nút lá hoặc nửa lá với con trái. Gọi u là cha của v và x là con trái của v (trong trường hợp v là nửa lá).

Khi loại bỏ v khỏi cây thay x vào vị trí của v, khi đó chiều cao cây con gốc x cũng như hệ số cân bằng của nó không thay đổi. Khi đó cũng có các trường hợp xảy ra như đối với phép chèn ta chỉ cần xây dựng thủ tục tái cân bằng cây sau đây

Procedure Rebalance(vT);

Begin

u:=v;

while (u<>T(r)) and (abs(B(u))<=1) do begin

Balance(u); u:=u.parent; (* u.parent là cha của u *) end ;

if (B(u)>=2) then

if (B(u.left)>0) then rotate_right(u) else

begin

rotate_left(u.left); rotate_right(u);

else

end

if (B(u)<=-2) then

if (B(u.right)<0) then rotate_left else

begin

rotate_right(u.right); rotate_left(u);

End;

end;

Một phần của tài liệu giáo trình toán rời rạc phần 2 (Trang 62 - 65)

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

(104 trang)
w