Professional Documents
Culture Documents
CTDL
CTDL
Cây AVL chính sự nâng cấp của cây BST (Binary Search Tree) nên
nếu bạn chưa biết gì về cây BST thì hãy đọc bài viết cây tìm kiếm
nhị phân này trước khi bắt đầu.
Vậy thì BST có điểm yếu gì mà phải nâng cấp, hãy cùng nhìn:
Có thể thấy rằng, khi ta thêm các phần tử theo thứ tự tăng dần
(giảm dần) thì cây không khác gì một Linked List (Danh sách liên
kết). Như vậy, ưu điểm của BST so với Linked List coi như cũng
không còn.
Cây AVL là cây nhị phân tìm kiếm cân bằng với “chiều cao” giữa
cây con bên trái và cây con bên phải chênh nhau không vượt quá
1. Hay nói cách khác, BST mà cây con bên trái và phải của mọi
Node có “chiều cao” chênh lệch không vượt 1 thì chính là cây
AVL.
Để xây dựng được cây AVL thì các bạn nắm rõ các yếu tố sau:
1.
1. Khái niệm “chiều cao” và cách tính.
2. Các kỹ thuật quay cây AVL
3. Các trường hợp cây bị lệch
Bạn có thể tính độ cao qua hàm đệ quy như cách dưới đây. Tuy
nhiên, mình sẽ không áp dụng vào code chính bởi vì khi dữ liệu
đầu vào cực lớn thì việc đệ quy để tính chiều cao một Node bằng
cách dựa vào tất cả các Node con là rất mất thời gian.
Có thể thấy cây BST khi không cân bằng sẽ bị lệch sang phía bên
trái hoặc bên phải. Để điều chỉnh lại ta cần phải quay cây sang
phía ngược lại.
X sẽ lên làm Node cha với con phải là root hay x.right = root
Về chiều cao, có thể thấy chỉ có 2 Node bị thay đổi chiều cao đó
là root và x. Vì root là con của x nên phải tính chiều cao của root
trước.
Hoàn toàn tương tự, gọi x y lần lượt là các con trái phải của root.
Và ta chỉ cần quan tâm 3 Node: root, y, y.left
Tiếp tục, hãy nhìn vào Node màu đỏ vừa mới được thêm vào. Ta
có thể thấy: Node đỏ nằm bên trái của Node X hay giá trị Node
đỏ < giá trị Node X. Vì vậy nên trường hợp này mới có tên là
“Trái trái“.
Tóm lại:
Xảy ra khi: height(X) – height(Y) > 1 và value(Đỏ) < value(X)
Có thể tưởng tượng rằng: khi nhìn tổng quan cây, thì cây bị lệch
sang bên trái; còn khi nhìn chi tiết bên trái, thì lại thấy cây
nghiêng về bên phải một xíu.
Xử lý: Vì cây con X bị nghiêng sang phải nên chỉ cần quay trái X
thì sẽ được trường hợp “Trái trái” như trước. Rồi sau đó quay phải
root như trường hợp 1.
Tóm lại:
Xử lý: rotateLeft(root)