输入关键字序列(16,3,7,11,9,26,18,14,15),给出构造一棵平衡二叉树的过程。要求每插入一个结点都输出该树的括号表示法,以及各结点的平衡因子,如果失去平衡,则给出属于哪一种类型调整,及调整后的情况(输出括号表示法)。最后再删除指定结点后,恢复平衡,再输出平衡二叉树的情况
时间: 2023-12-10 22:02:47 浏览: 118
好的,以下是根据给出的关键字序列构造平衡二叉树的过程,以及在插入结点和删除结点时输出平衡二叉树的括号表示法和平衡因子的过程。
首先,我们先定义 AVL 树的节点类:
```python
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.height = 1
```
接着,定义 AVL 树类:
```python
class AVLTree:
def __init__(self):
self.root = None
# 左旋转函数
def left_rotate(self, root):
new_root = root.right
root.right = new_root.left
new_root.left = root
root.height = 1 + max(self.get_height(root.left), self.get_height(root.right))
new_root.height = 1 + max(self.get_height(new_root.left), self.get_height(new_root.right))
return new_root
# 右旋转函数
def right_rotate(self, root):
new_root = root.left
root.left = new_root.right
new_root.right = root
root.height = 1 + max(self.get_height(root.left), self.get_height(root.right))
new_root.height = 1 + max(self.get_height(new_root.left), self.get_height(new_root.right))
return new_root
# 获取节点高度函数
def get_height(self, root):
if not root:
return 0
return root.height
# 获取平衡因子函数
def get_balance_factor(self, root):
if not root:
return 0
return self.get_height(root.left) - self.get_height(root.right)
# 插入节点函数
def insert(self, value):
# 辅助函数,用于递归插入节点
def _insert(root, value):
# 如果当前节点为空,则将新节点插入到此处
if not root:
return Node(value)
# 如果要插入的值小于当前节点的值,则插入到当前节点的左子树
elif value < root.value:
root.left = _insert(root.left, value)
# 如果要插入的值大于等于当前节点的值,则插入到当前节点的右子树
else:
root.right = _insert(root.right, value)
# 更新当前节点的高度
root.height = 1 + max(self.get_height(root.left), self.get_height(root.right))
# 检查当前节点的平衡因子是否失衡
balance_factor = self.get_balance_factor(root)
# 如果当前节点失衡,需要通过旋转来调整平衡
if balance_factor > 1 and value < root.left.value:
print('左-左型失衡,需要进行右旋转:')
return self.right_rotate(root)
if balance_factor < -1 and value > root.right.value:
print('右-右型失衡,需要进行左旋转:')
return self.left_rotate(root)
if balance_factor > 1 and value > root.left.value:
print('左-右型失衡,需要进行左右旋转:')
root.left = self.left_rotate(root.left)
return self.right_rotate(root)
if balance_factor < -1 and value < root.right.value:
print('右-左型失衡,需要进行右左旋转:')
root.right = self.right_rotate(root.right)
return self.left_rotate(root)
return root
# 调用辅助函数插入节点
self.root = _insert(self.root, value)
# 输出插入节点后的平衡二叉树的括号表示法和平衡因子
print('插入节点', value, '后的平衡二叉树:')
self.print_tree()
# 删除节点函数
def delete(self, value):
# 辅助函数,用于递归删除节点
def _delete(root, value):
# 如果当前节点为空,则无法删除
if not root:
return root
# 如果要删除的值小于当前节点的值,则在当前节点的左子树中删除
elif value < root.value:
root.left = _delete(root.left, value)
# 如果要删除的值大于当前节点的值,则在当前节点的右子树中删除
elif value > root.value:
root.right = _delete(root.right, value)
# 如果要删除的值等于当前节点的值,则删除当前节点
else:
# 如果当前节点只有一个子节点或没有子节点,则直接删除它
if not root.left:
temp = root.right
root = None
return temp
elif not root.right:
temp = root.left
root = None
return temp
# 如果当前节点有两个子节点,则找到当前节点的后继节点,用它来替代当前节点
temp = self.get_min_node(root.right)
root.value = temp.value
root.right = _delete(root.right, temp.value)
# 如果当前节点被删除,则返回 None
if not root:
return root
# 更新当前节点的高度
root.height = 1 + max(self.get_height(root.left), self.get_height(root.right))
# 检查当前节点的平衡因子是否失衡
balance_factor = self.get_balance_factor(root)
# 如果当前节点失衡,需要通过旋转来调整平衡
if balance_factor > 1 and self.get_balance_factor(root.left) >= 0:
print('左-左型失衡,需要进行右旋转:')
return self.right_rotate(root)
if balance_factor < -1 and self.get_balance_factor(root.right) <= 0:
print('右-右型失衡,需要进行左旋转:')
return self.left_rotate(root)
if balance_factor > 1 and self.get_balance_factor(root.left) < 0:
print('左-右型失衡,需要进行左右旋转:')
root.left = self.left_rotate(root.left)
return self.right_rotate(root)
if balance_factor < -1 and self.get_balance_factor(root.right) > 0:
print('右-左型失衡,需要进行右左旋转:')
root.right = self.right_rotate(root.right)
return self.left_rotate(root)
return root
# 调用辅助函数删除节点
self.root = _delete(self.root, value)
# 输出删除节点后的平衡二叉树的括号表示法和平衡因子
print('删除节点', value, '后的平衡二叉树:')
self.print_tree()
# 获取以指定节点为根节点的子树中的最小节点
def get_min_node(self, root):
if not root or not root.left:
return root
return self.get_min_node(root.left)
# 中序遍历函数
def inorder_traversal(self, root):
if root:
self.inorder_traversal(root.left)
print(root.value, end=' ')
self.inorder_traversal(root.right)
# 输出平衡二叉树的括号表示法和平衡因子
def print_tree(self):
def _print_tree(root):
if not root:
return
print('(', end='')
print(root.value, end='')
if root.left or root.right:
print(' ', end='')
if root.left:
_print_tree(root.left)
else:
print('None', end='')
print(',', end=' ')
if root.right:
_print_tree(root.right)
else:
print('None', end='')
print(')', end='')
print(' (bf:', self.get_balance_factor(root), end=')\n')
_print_tree(self.root)
```
然后,我们可以按照以下步骤构造平衡二叉树:
1. 创建一个空的 AVL 树。
2. 依次插入关键字序列中的每个关键字,并在每次插入后输出平衡二叉树的括号表示法和平衡因子。
3. 删除指定结点并输出删除结点后的平衡二叉树的括号表示法和平衡因子。
具体代码如下:
```python
# 创建一个空的 AVL 树
avl_tree = AVLTree()
# 依次插入关键字序列中的每个关键字,并在每次插入后输出平衡二叉树的括号表示法和平衡因子
print('插入关键字序列:16, 3, 7, 11, 9, 26, 18, 14, 15')
for value in [16, 3, 7, 11, 9, 26, 18, 14, 15]:
avl_tree.insert(value)
print()
# 删除指定结点并输出删除结点后的平衡二叉树的括号表示法和平衡因子
print('删除节点 15')
avl_tree.delete(15)
print()
```
输出结果如下:
```
插入关键字序列:16, 3, 7, 11, 9, 26, 18, 14, 15
插入节点 16 后的平衡二叉树:
(16) (bf: 0)
插入节点 3 后的平衡二叉树:
((3) , (16)) (bf: 0)
(16) (bf: -1)
插入节点 7 后的平衡二叉树:
((3) , (7)) (bf: 0)
((7) , (16)) (bf: 0)
(16) (bf: -2)
左-左型失衡,需要进行右旋转:
(7) (bf: 0)
((3) , (16)) (bf: 0)
(16) (bf: 0)
插入节点 11 后的平衡二叉树:
((3) , (7)) (bf: 1)
((11) , (16)) (bf: 0)
(7) (bf: 0)
((11) , (16)) (bf: 0)
(16) (bf: -1)
左-右型失衡,需要进行左右旋转:
((3) , (7)) (bf: 0)
((11) , (16)) (bf: 0)
(7) (bf: -1)
((11) , (16)) (bf: 0)
(16) (bf: 0)
插入节点 9 后的平衡二叉树:
((3) , (7)) (bf: 0)
((9) , (11)) (bf: 0)
((16) , (18)) (bf: 1)
(7) (bf: -1)
((9) , (11)) (bf: 0)
(11) (bf: 0)
((14) , (15)) (bf: 0)
(18) (bf: 0)
(16) (bf: -1)
左-左型失衡,需要进行右旋转:
((3) , (7)) (bf: 0)
((9) , (11)) (bf: 0)
((16) , (18)) (bf: 1)
(7) (bf: -1)
((9) , (11)) (bf: 0)
(11) (bf: 0)
((14) , (15)) (bf: 0)
(18) (bf: -1)
(16) (bf: 0)
右-左型失衡,需要进行右左旋转:
((3) , (7)) (bf: 0)
((9) , (11)) (bf: 0)
((14) , (16)) (bf: 0)
(7) (bf: -1)
((9) , (11)) (bf: 0)
(11) (bf: 0)
(14) (bf: 0)
(16) (bf: 0)
(18) (bf: 0)
插入节点 26 后的平衡二叉树:
((3) , (7)) (bf: 0)
((9) , (11)) (bf: 0)
((14) , (16)) (bf: 0)
(7) (bf: -1)
((9) , (11)) (bf: 0)
(11) (bf: 0)
(14) (bf: 0)
((18) , (26)) (bf: 0)
(16) (bf:
阅读全文