- 左旋和右旋示意图
- 四种情况及解决方案
- AVL 的逻辑分析
- AVL in Go
旋转
左旋
右旋
四种情况
左左
右右
左右
右左
逻辑分析
记录当前节点的状态 Abs(state) <= 1 ,每次发生一点不平衡就会修正,分为以上四种情况。
AVL in Golang
这段代码来自:gods
// Tree holds elements of the AVL tree.type Tree struct {Root *Node // Root nodeComparator utils.Comparator // Key comparatorsize int // Total number of keys in the tree}// Node is a single element within the treetype Node struct {Key interface{}Value interface{}Parent *Node // Parent nodeChildren [2]*Node // Children nodesb int8}
其中 b 是用来表明节点是否平衡的,children[0] 代表左节点,children[1] 代表右节点。后面通过亦或运算来统一左旋和右旋,很优秀。
func singlerot(c int8, s *Node) *Node {s.b = 0s = rotate(c, s)s.b = 0return s}func doublerot(c int8, s *Node) *Node {a := (c + 1) / 2r := s.Children[a]s.Children[a] = rotate(-c, s.Children[a])p := rotate(c, s)switch {default:s.b = 0r.b = 0case p.b == c:s.b = -cr.b = 0case p.b == -c:s.b = 0r.b = c}p.b = 0return p}// c < 0 时为右旋,c > 0 时为左旋func rotate(c int8, s *Node) *Node {a := (c + 1) / 2r := s.Children[a]s.Children[a] = r.Children[a^1]if s.Children[a] != nil {s.Children[a].Parent = s}r.Children[a^1] = sr.Parent = s.Parents.Parent = rreturn r}
数学基础:
通过亦或,将左旋和右旋统一在一起,singlerot 统一了左左和右右的情况,doublerot 统一的左右和右左的情况。
整个流程通过参数 c 来控制左旋还是右旋,由 c 可以获取左节点还是有节点,节点位置 a = (c + 1) / 2
这里面只列出了部分关键代码,完整代码青岛 Github 上自行查看






