跳至主要内容

[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 繼承​