avl树

简述

二叉搜索树的最坏情况下搜索的时间复杂度可能达到O(n),avl树在普通的二叉搜索树的基础上加入了自动平衡的特性,其左子树与右子树的高度差的绝对值不大于2,且左子树与右子树也是一棵avl树

旋转

avl树进行插入或者删除后,通过旋转来满足平衡性质
总共有4种情况需要旋转

  • LL: 左孩子的左子树进行了插入导致了不平衡,此时需要右旋
  • RR:右孩子的右子树进行了插入导致了不平衡,此时需要左旋
  • LR:左孩子的右子树进行了插入,此时需要先左旋再右旋
  • RL:右孩子的左子树进行了插入,此时需要先右旋再左旋

代码实现

package main

import (
	"fmt"
	"math"
)

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

type AVL struct {
	root *Node
}

func BalancedFactor(root *Node) int {
	if root == nil {
		return 0
	}
	return Height(root.right)-Height(root.left)
}

func Height(node *Node) int{
	if node==nil {
		return 0
	}
	return node.height
}


func LeftRotation(root *Node)*Node {
	right := root.right
	root.right = right.left
	right.left=root
	// 长度变更
	root.height = int(math.Max(float64(Height(root.right)), float64(Height(root.left)))) + 1
	return right
}

func RightRotation(root *Node)*Node {
	left := root.left
	root.left = left.right
	left.right=root
	root.height = int(math.Max(float64(Height(root.right)), float64(Height(root.left)))) + 1
	return left
}

func RightLeftRotation(root *Node)*Node {
	root.right=RightRotation(root.right)
	return LeftRotation(root)
}

func LeftRightRotation(root *Node)*Node {
	root.left=LeftRotation(root.left)
	return RightRotation(root)
}

func add(root *Node, node *Node) *Node{
	if root == nil {
		return node
	}
	if root.value>node.value {
		root.left=add(root.left,node)
	} else {
		root.right=add(root.right,node)
	}

	root.height= int(math.Max(float64(Height(root.right)), float64(Height(root.left)))) + 1
	if BalancedFactor(root) > 1 && BalancedFactor(root.right) < 0{
		return RightLeftRotation(root)
	} else if BalancedFactor(root) < -1 && BalancedFactor(root.left) > 0 {
		return LeftRightRotation(root)
	} else if BalancedFactor(root) > 1 {
		return LeftRotation(root)
	} else if BalancedFactor(root) < -1 {
		return RightRotation(root)
	}

	return root
}

func delete(root *Node, val int) *Node {
	if root == nil {
		return nil
	}

	retRoot := root

	if root.value > val {
		root.left = delete(root.left, val)
	} else if root.value < val {
		root.right = delete(root.right, val)
	} else {
		if root.left == nil {
			retRoot = root.right
		} else if root.right == nil {
			retRoot = root.left
		} else {
			right := root.right
			rightLeft := right.left
			for rightLeft != nil {
				right = rightLeft
				rightLeft = rightLeft.left
			}
			retRoot = right
			// 这里赋值顺序要注意
			retRoot.right = delete(root.right, retRoot.value)
			retRoot.left = root.left
		}
	}
	if BalancedFactor(retRoot) > 1 && BalancedFactor(retRoot.right) < 0{
		return RightLeftRotation(retRoot)
	} else if BalancedFactor(retRoot) < -1 && BalancedFactor(retRoot.left) > 0 {
		return LeftRightRotation(retRoot)
	} else if BalancedFactor(retRoot) > 1 {
		return LeftRotation(retRoot)
	} else if BalancedFactor(retRoot) < -1 {
		return RightRotation(retRoot)
	}

	return retRoot
}

func (avl *AVL)Add(node *Node) {
	if node == nil {
		return
	}
	root := avl.root
	avl.root = add(root, node)
}

func (avl *AVL)Delete(val int) {
	root := avl.root
	avl.root = delete(root, val)
}

func (avl *AVL) LevelPrint() {
	root := avl.root
	if root == nil {
		return
	}
	nodeList := make([]*Node,0)
	nodeList = append(nodeList, root)
	for len(nodeList) > 0 {
		a := nodeList[0]
		fmt.Print(" ", a.value)
		nodeList = nodeList[1:]
		if a.left != nil {
			nodeList = append(nodeList, a.left)
		}
		if a.right != nil {
			nodeList = append(nodeList, a.right)
		}

	}
}

func IsBalanced(root *Node) bool{
	if root == nil {
		return true
	}
	if int(math.Abs(float64(BalancedFactor(root)))) > 1 {
		return false
	}

	return IsBalanced(root.right) && IsBalanced(root.left)
}

func (avl *AVL) Print() {
	PrePrint(avl.root)
	fmt.Println()
	MidPrint(avl.root)
	fmt.Println()
}
func PrePrint(node *Node) {
	if node == nil {
		return
	}
	fmt.Print(" ", node.value)
	PrePrint(node.left)
	PrePrint(node.right)
}
func MidPrint(node *Node) {
	if node == nil {
		return
	}
	MidPrint(node.left)
	fmt.Print(" ", node.value)
	MidPrint(node.right)
}

func main() {
	avl := &AVL{}
	v := []int{6,7,3,2,5,4,8,9,1,0,  44,23,12,65,88,45,13}
	for _, i := range v {
		avl.Add(&Node{value: i, height: 1})
		fmt.Println(IsBalanced(avl.root))
	}
	avl.Print()
	fmt.Println("delete................")
	v = []int{0,1,6,5,7,9,8,2,3,4,   13,45,65,12,23,44,88}
	for _, i := range v {
		avl.Delete(i)
		fmt.Println(IsBalanced(avl.root))
	}
}

avl树性能

每次进行插入时,avl树只需经过最多一次操作就可以达到平衡。
而进行删除时,可能需要对从一整条路径进行平衡操作,复杂度可达log(n),这就是相比于红黑树来说劣势的地方了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值