平衡因子计算如下:balanceFactor = height(left-subtree) - height(right-subtree)。对于检查的每个节点,如果平衡因子保持-1,0或+1,则不需要旋转。
然而,在OCaml中,它似乎使用2的平衡因子
let bal l x d r =
let hl = match l with Empty -> 0 | Node(_,_,_,_,h) -> h in
let hr = match r with Empty -> 0 | Node(_,_,_,_,h) -> h in
if hl > hr + 2 then begin
match l with
Empty -> invalid_arg "Map.bal"
| Node(ll, lv, ld, lr, _) ->
if height ll >= height lr then
create ll lv ld (create lr x d r)
else begin
match lr with
Empty -> invalid_arg "Map.bal"
| Node(lrl, lrv, lrd, lrr, _)->
create (create ll lv ld lrl) lrv lrd (create lrr x d r)
end
end else if hr > hl + 2 then begin
match r with
Empty -> invalid_arg "Map.bal"
| Node(rl, rv, rd, rr, _) ->
if height rr >= height rl then
create (create l x d rl) rv rd rr
else begin
match rl with
Empty -> invalid_arg "Map.bal"
| Node(rll, rlv, rld, rlr, _) ->
create (create l x d rll) rlv rld (create rlr rv rd rr)
end
end else
Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1))
为什么吗
答案 0 :(得分:8)
在AVL树中,您可以将最大高度差看作可调整参数。他们必须选择2来在插入/移除的重新平衡成本和查找成本之间进行权衡。
由于您似乎对这些事情感兴趣,我建议您查看这个this paper,其中有正确证明OCaml的Set模块的正确性,该模块使用相同的AVL树,通过这样做,他们实际上找到了重新平衡计划中的一个错误...虽然不是严格等同的实现,但我从这个this paper中学到了很多东西。