算法Go语言描述📌treestruct📌2-avl.go
package treestruct

/*
AVL树是是高度平衡而非完美平衡的,如下是一棵AVL树:
       7
      / \
     5   8
	/ \   \
   4   6   9
 /
3
AVL树满足BST的性质,Search,Min,Max,InOrderTraversal等方法逻辑完全相同,Insert和Delete操作后需要调整平衡性。
*/

type AvlNode struct {
	value  int      // 值
	bf     int8     // 平衡因子(Balance-Factor:右子树高度-左子树高度)
	parent *AvlNode // 上层结点
	left   *AvlNode // 左子树
	right  *AvlNode // 右子树
}
type AvlTree struct {
	root *AvlNode
}

/*
按照BST的规则将新结点插入到AVL树中。
插入结点是parent结点的左叶子则p.bf-1,插入结点是parent结点的右叶子则p.bf+1。
如果parent的bf为0,说明插入前是±1,未改变平衡性,插入成功。
如果parent的bf为±1,说明插入前平衡因子为0,以parent为根的树高度增加,需要继续向上寻找。
如果parent的bf为±2,则找到最小不平衡树p,需要对p结点做旋转处理。
*/

func (tree *AvlTree) Insert(v int) bool {
	if tree.root == nil {
		tree.root = &AvlNode{value: v}
		return true
	}
	p := tree.root
	for {
		if v == p.value {
			return false
		}
		if v < p.value {
			if p.left == nil {
				p.left = &AvlNode{value: v, parent: p}
				break
			}
			p = p.left
		} else {
			if p.right == nil {
				p.right = &AvlNode{value: v, parent: p}
				break
			}
			p = p.right
		}
	}
	var cbf int8
	for p != nil {
		if v < p.value {
			p.bf--
		} else {
			p.bf++
		}
		if p.bf == 1 || p.bf == -1 {
			cbf = p.bf
			p = p.parent
			continue
		}
		if p.bf == -2 {
			if cbf < 0 { //LL型
				tree.rotateR(p)
			} else { //LR型
				tree.rotateLR(p)
			}
		} else if p.bf == 2 {
			if cbf > 0 { //RR型
				tree.rotateL(p)
			} else { //RL型
				tree.rotateRL(p)
			}
		}
		break
	}
	return true
}

/*
删除规则与BST类似。
删除结点是parent结点的左叶子则p.bf+1,删除结点是parent结点的右叶子则p.bf-1。
如果parent的bf为±1,说明删除前为0,未改变子树高度,无需调整。
如果parent的bf为0,说明删除前是±1,以parent为根的树高度减少,需要继续向上寻找。
如果parent的bf为±2,则需要对p结点做旋转处理,再继续向上寻找。
    !
    3
   / \
  2   6
 /   / \
1   4   7
     \   \
      5   8
1: n=nil(o.child), p(2).bf++
8: n=nil(o.child), p(7).bf--
2: n(1)=o(2).left, p(3).bf++
7: n(8)=o(7).right, p(6).bf--
6: n(7)=o(6).right, n(7).bf=o(6).bf-1
3: n(4)!=o(3).right, n(4).bf=o(3).bf, n.parent(6).bf++
*/

func (tree *AvlTree) Delete(v int) bool {
	o := tree.root //待删除old结点
	for o != nil {
		if v == o.value { //找到待删除结点
			break
		}
		if v < o.value {
			o = o.left
		} else {
			o = o.right
		}
	}
	if o == nil { //未找到
		return false
	}
	var n *AvlNode //替换old的new结点
	p := o.parent  //向上调整的起点
	if o.left == nil {
		n = o.right //左子树为空,右子树替换(含nil)
	} else if o.right == nil {
		n = o.left //右子树为空,左子树替换
	} else { //或使用对称逻辑
		n = o.right //右子树的最小结点
		for n.left != nil {
			n = n.left
		}
		n.left = o.left //new结点拼上old结点的左子树
		o.left.parent = n
		if n.parent == o { //即n==o.right
			n.bf = o.bf - 1
			p = n
		} else {
			n.bf = o.bf
			n.parent.bf++
			p = n.parent
			n.parent.left = n.right
			if n.right != nil {
				n.right.parent = n.parent
			}
			n.right = o.right
			o.right.parent = n
		}
	}
	if n != nil {
		n.parent = o.parent
	}
	if o.parent == nil {
		tree.root = n
	} else {
		if v < o.parent.value {
			o.parent.left = n //是其左子树
			if p == o.parent {
				p.bf++
			}
		} else {
			o.parent.right = n //是其右子树
			if p == o.parent {
				p.bf--
			}
		}
	}
	for p != nil {
		if p.bf == -1 || p.bf == 1 {
			break
		}
		if p.bf == -2 {
			if p.left.bf <= 0 { //LL型
				tree.rotateR(p)
			} else { //LR型
				tree.rotateLR(p)
			}
			p = p.parent
		} else if p.bf == 2 {
			if p.right.bf >= 0 { //RR型
				tree.rotateL(p)
			} else { //RL型
				tree.rotateRL(p)
			}
			p = p.parent
		} else {
			r := p.parent
			if r != nil {
				if p.value < r.value {
					r.bf++
				} else {
					r.bf--
				}
			}
			p = r
		}
	}
	return true
}

func (tree *AvlTree) rotateR(p *AvlNode) {
	r := p.parent
	c := p.left
	p.left = c.right
	if c.right != nil {
		c.right.parent = p
	}
	c.right = p
	p.parent = c
	c.parent = r
	if r == nil {
		tree.root = c
	} else {
		if c.value < r.value {
			r.left = c
		} else {
			r.right = c
		}
	}
	if p.bf == -2 && c.bf == 0 {
		p.bf, c.bf = -1, 1
	} else if p.bf == -2 && c.bf == -1 {
		p.bf, c.bf = 0, 0
	} else if p.bf == -2 && c.bf == -2 {
		p.bf, c.bf = 1, 0
	} else if p.bf == -1 && c.bf == 1 {
		p.bf, c.bf = 0, 2
	} else if p.bf == -1 && c.bf == 0 {
		p.bf, c.bf = 0, 1
	} else if p.bf == -1 && c.bf == -1 {
		p.bf, c.bf = 1, 1
	}
}
func (tree *AvlTree) rotateL(p *AvlNode) {
	r := p.parent
	c := p.right
	p.right = c.left
	if c.left != nil {
		c.left.parent = p
	}
	c.left = p
	p.parent = c
	c.parent = r
	if r == nil {
		tree.root = c
	} else {
		if c.value < r.value {
			r.left = c
		} else {
			r.right = c
		}
	}
	if p.bf == 2 && c.bf == 0 {
		p.bf, c.bf = 1, -1
	} else if p.bf == 2 && c.bf == 1 {
		p.bf, c.bf = 0, 0
	} else if p.bf == 2 && c.bf == 2 {
		p.bf, c.bf = -1, 0
	} else if p.bf == 1 && c.bf == -1 {
		p.bf, c.bf = 0, -2
	} else if p.bf == 1 && c.bf == 0 {
		p.bf, c.bf = 0, -1
	} else if p.bf == 1 && c.bf == 1 {
		p.bf, c.bf = -1, -1
	}
}
func (tree *AvlTree) rotateLR(p *AvlNode) {
	tree.rotateL(p.left)
	tree.rotateR(p)
}
func (tree *AvlTree) rotateRL(p *AvlNode) {
	tree.rotateR(p.right)
	tree.rotateL(p)
}