深入理解平衡二叉树AVL与Python实现(2)

class Node(OrderedMap.Node):
        def __init__(self, element, parent=None, left=None, right=None):
            super().__init__(element,parent,left,right)
            self.height = 0

def left_height(self):
            return self.left.height if self.left is not None else 0

def right_height(self):
            return self.right.height if self.right is not None else 0

接下来定义4中调整的非公开方法

def _left_left(self,p):
    this = p.node        # 有变化的就4个节点
    left = this.left
    parent = this.parent
    left_right = this.left.right
    if parent is not None:
        if this is parent.left:
            parent.left = left
        else:
            parent.right = left
    else:
        self._root = left
    this.parent = left
    left.parent = parent
    this.left = left_right
    left.right = this
    if left_right is not None:
        left_right.parent = this

def _right_right(self,p):
    this = p.node                # 有变化的就4个节点
    right = this.right
    parent = this.parent
    right_left = this.right.left
    if parent is not None:
        if this is parent.left:
            parent.left = right
        else:
            parent.right = right
    else:
        self._root = right
    this.parent = right
    right.parent = parent
    this.right = right_left
    right.left = this
    if right_left is not None:
        right_left.parent = this

def _left_right(self,p):
    self._right_right(self.left(p))
    self._left_left(p)

def _right_left(self,p):
    self._left_left(self.right(p))
    self._right_right(p)


然后是用于平衡二叉树的方法,也就是根据情况调用上边那4种策略

def _isbalanced(self,p):
    """判断节点是否平衡"""

return abs(p.node.left_height() - p.node.right_height()) <= 1

def _recompute_height(self,p):
    """重新计算高度"""
    p.node.height = 1 + max(p.node.left_height(),p.node.right_height())

def _rebalanced(self,p):
    while p is not None:
        if self._isbalanced(p):
            self._recompute_height(p)
            p = self.parent(p)
        else:

if p.node.left_height()>p.node.right_height() and p.node.left.left_height()>p.node.left.right_height():
                # LL的情况,只有自己和左孩子的高度可能变化
                self._left_left(p)
            elif p.node.right_height()>p.node.left_height() and p.node.right.right_height()>p.node.right.left_height():
                # RR的情况,只有自己和右孩子的高度可能变化
                self._right_right(p)
            elif p.node.left_height()>p.node.right_height() and p.node.left.left_height()<p.node.left.right_height():
                # LR的情况,只有自己和左孩子和左孩子的右孩子的高度可能变化
                left = self.left(p)
                self._left_right(p)
                self._recompute_height(left)
            else:
                # RL的情况,只有自己和右孩子和右孩子的左孩子的高度可能变化
                right = self.right(p)
                self._right_left(p)
                self._recompute_height(right)
            while p is not None:
                # 调整所有p的祖先的高度
                self._recompute_height(p)
                p = self.parent(p)

然后把方法封装成删除时和插入时的两个方法,虽然执行的内容是相同的

def _rebalanced_insert(self,p):
    """插入时的平衡调整"""
    self._rebalanced(p)

def _rebalanced_delete(self, p):
    """删除时的平衡调整"""
    self._rebalanced(p)

最后重写一下setitem方法与删除时调用的方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8c7b569c5c9f24df4ea667a8fa775c98.html