平衡二叉树(AVL树)
平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。
时间复杂度:AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)
AVL树节点定义
class Node(object): def __init__(self, val, left=None, right=None, height=-1): self.val = val self.left = left self.right = right self.height = height
二叉平衡树失去平衡的情况和调整策略
1. LL
LeftLeft,也称为"左左"。插入或删除一个节点后,根节点的左子树的左子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL树失去了平衡。
def leftLeftRotate(self, node):
k = node.left
node.left = k.right
k.right = node
node.height = max(node.left.height, node.right.height) + 1
k.height = max(k.left.height, k.right.height) + 1
return k
2. RR
RightRight,称为"右右"。插入或删除一个节点后,根节点的右子树的右子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL树失去了平衡。
def rightRightRotate(self, node): k = node.right node.right = k.left k.left = node node.height = max(node.left.height, node.right.height) + 1 k.height = max(k.left.height, k.right.height) + 1 return k
3. LR
LeftRight,也称为"左右"。插入或删除一个节点后,根节点的左子树的右子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL树失去了平衡。
def leftRightRotate(self, node): node.left = self.rightRightRotate(node.left) return self.leftLeftRotate(node)
4. RL
RightLeft,称为"右左"。插入或删除一个节点后,根节点的右子树的左子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL树失去了平衡。
def rightLeftRotate(self, node): node.right = self.leftLeftRotate(node.right) return self.rightRightRotate(node)
插入节点
def insert(self, root, val): if root == None: root = Node(val = val, height = 0) return root if val < root.left: root.left = self.insert(root.left, val) if root.left.height - root.right.height == 2: #在左子树插入节点,可能出现左比右高 if val < root.left.val: #LL root = self.leftLeftRotate(root) else: #LR root = self.leftRightRotate(root) else: root.right = self.insert(root.right, val) if root.right.height - root.left.height == 2: #在右子树插入节点,可能出现右比左高 if val < root.right.key: #RL root = self.rightLeftRotate(root) else: #RR root = self.rightRightRotate(root) root.height = max(root.left.height, root.right.height) + 1 return root
删除节点
def delNode(self, root, val): if root == None: return None if val < root.val: root.left = self.delNode(root.left, val) if root.right.height - root.left.height == 2: #删除左子树中节点,可能出现右比左高 if root.right.right.height >= root.right.left.height: root = self.rightRightRotate(root) #RR else: root = self.rightLeftRotate(root) #RL elif val > root.val: root.right = self.delNode(root.right, val) if root.left.height - root.right.height == 2: #删除右子树中节点,可能出现左比右高 if root.left.left.height >= root.left.right.height: root = self.leftLeftRotate(root) #LL else: root = self.leftRightRotate(root) #LR elif root.left and root.right: if root.left.height <= root.right.height: minNode = self.findMin(root.right) root.val = minNode.val root.right = self.delNode(root.right, minNode.val) else: maxNode = self.findMax(root.left) root.val = maxNode.val root.left = self.delNode(root.left, maxNode.val) else: if root.right: root = root.right else: root = root.left root.height = max(root.left.height, root.right.height) + 1 return root
全部代码
class AVLTree(object): def LeftLeftRotate(self, node): k = node.left node.left = k.right k.right = node node.height = max(node.left.height, node.right.height) + 1 k.height = max(k.left.height, k.right.height) + 1 return k def rightRightRotate(self, node): k = node.right node.right = k.left k.left = node node.height = max(node.left.height, node.right.height) + 1 k.height = max(k.left.height, k.right.height) + 1 return k def leftRightRotate(self, node): node.left = self.rightRightRotate(node.left) return self.leftLeftRotate(node) def rightLeftRotate(self, node): node.right = self.leftLeftRotate(node.right) return self.rightRightRotate(node) def insert(self, root, val): if root == None: root = Node(val = val, height = 0) return root if val < root.left: root.left = self.insert(root.left, val) if root.left.height - root.right.height == 2: if val < root.left.val: #LL root = self.leftLeftRotate(root) else: #LR root = self.leftRightRotate(root) else: root.right = self.insert(root.right, val) if root.right.height - root.left.height == 2: if val < root.right.key: #RL root = self.rightLeftRotate(root) else: #RR root = self.rightRightRotate(root) root.height = max(root.left.height, root.right.height) + 1 return root def delNode(self, root, val): if root == None: return None if val < root.val: root.left = self.delNode(root.left, val) if root.right.height - root.left.height == 2: #删除左子树中节点,可能出现右比左高 if root.right.right.height >= root.right.left.height: root = self.rightRightRotate(root) #RR else: root = self.rightLeftRotate(root) #RL elif val > root.val: root.right = self.delNode(root.right, val) if root.left.height - root.right.height == 2: #删除右子树中节点,可能出现左比右高 if root.left.left.height >= root.left.right.height: root = self.leftLeftRotate(root) #LL else: root = self.leftRightRotate(root) #LR elif root.left and root.right: if root.left.height <= root.right.height: minNode = self.findMin(root.right) root.val = minNode.val root.right = self.delNode(root.right, minNode.val) else: maxNode = self.findMax(root.left) root.val = maxNode.val root.left = self.delNode(root.left, maxNode.val) else: if root.right: root = root.right else: root = root.left root.height = max(root.left.height, root.right.height) + 1 return root def findMin(self, root): if root == None: return None if root.left == None: return root return self.findMin(root.left) def findMax(self, root): if root == None: return None if root.right == None: return root return self.findMax(root.right)
参考博客
https://www.cnblogs.com/skywang12345/p/3576969.html
https://www.cnblogs.com/linxiyue/p/3659448.html?utm_source=tuicool&utm_medium=referral