跳至主要内容

[DS] AVL Tree

Feature

A balanced BST is a BST that h = O(log N). AVL Tree (Adelson-Velskii & Landis, 1962) that is named after its inventor: Adelson-Velskii and Landis.

...detail TBD ...

extends BST

AVL Tree 亦是一種 BST, 所有對 BST 的操作都適用於 AVL Tree. 適合類別界面封裝概念, 操作時無須考慮是由那一種 Tree 實作, 透過類別封裝界面操作即可.

另一點則是實作上 AVL Tree 中許多函式都可以直接沿用 BST 界面, 也適合用繼承以利程式重複使用與維護.

type AVLNode struct {
value int
height int
left *AVLNode
right *AVLNode
}

func newAVLNode(v int) *AVLNode {
return &AVLNode{
value: v,
height: 1,
left: nil,
right: nil,
}
}

height(v)

height(v): The number of edges on the path from vertex v down to its deepest leaf. This attribute is saved in each vertex so we can access a vertex's height in O(1) without having to recompute it every time.

v.height = -1 (if v is an empty tree)
v.height = max(v.left.height, v.right.height) + 1 (otherwise)

// Balance Factor
v.bf = v.left.height - v.right.height

Method

rebalance

AVL Tree needs to check if still balance after modified

check balance factor of this and its children
case1: this.rotateRight
case2: this.left.rotateLeft, this.rotateRight
case3: this.rotateLeft
case4: this.right.rotateRight, this.rotateLeft
this is balanced
func (n *AVLNode) rotate() *AVLNode {
left := n.left.getHeight()
right := n.right.getHeight()
bf := left - right

if bf > 1 {
if n.left.left.getHeight() < n.left.right.getHeight() {
n.left = n.left.rotateLeft()
}
return n.rotateRight()
} else if bf < -1 {
if n.right.left.getHeight() > n.right.right.getHeight() {
n.right = n.right.rotateRight()
}
return n.rotateLeft()
} else {
n.updateHeight()
return n
}
}

rotate Left/Right

func (n *AVLNode) rotateLeft() *AVLNode {
result := n.right
t := result.left

n.right = t
n.height--

result.left = n
return result
}

func (n *AVLNode) rotateRight() *AVLNode {
result := n.left
t := result.right

n.left = t
n.height--

result.right = n
return result
}

insert(v)

insert v
rebalance tree
func (n *AVLNode) insert(val int) IBSTNode {
return n.insertHelper(val)
}

func (n *AVLNode) insertHelper(val int) *AVLNode {
if n == nil { return newAVLNode(val) }

if n.value > val { n.left = n.left.insertHelper(val) }
else { n.right = n.right.insertHelper(val) }

return n.rotate()
}

remove(v)

remove v
rebalance tree
func (n *AVLNode) remove(val int) IBSTNode {
return n.removeHelper(val)
}

func (n *AVLNode) removeHelper(val int) *AVLNode {
// remove v: same as BSTNode
// ,,,
return n.rotate()
}

小結

Binary Heap 一些特性適合練習與解釋 Class 中的 private / public / class method. 而 BST / AVL Tree 則很適合 OOP 中的繼承和封裝概念.

這篇盡量以各語言中原生或模擬繼承的方式實作 AVL 對 BST 的繼承. 而限於 Golang 的特性, 繼承和 Overriding 會讓程式變得過於複雜, 反倒失去 Golang keep in simple 哲學, 僅用 interface 來封裝 AVL Tree Node.

See Also

AVL

Inheritance 繼承