文章目录
4. 二叉搜索树(BST,Binary Search Tree)
4.1 性质
- 左子树节点值都小于根结点值
- 右子树节点值都大于根结点值
- 子树又是一个搜索树
4.2 搜索树的函数
- 查找元素,返回节点地址
def find(x, BST):
while BST is not None:
if x>BST.data:
BST = BST.right
elif x < BST.data:
BST = BST.left)
else:
return BST
return None
- 查找最小元素在的节点地址
def findMin(BST):
if BST is None:
return None
elif BST.left is None:
return BST
else:
findMin(BST)
- 找最大元素的节点地址(查找最右节点)
- 插入值
def insert(x, BST):
if(!BST):
#生成二叉树
BST = Node(x)
else:
if(x < BST.Data):
BST.left = Insert(x,BST.left)
elif(x > BST.Data):
BST.right = Insert(x,BST.right)
return BST
- 删除
#如果是叶节点,直接删除
#如果是只有一个子节点的节点,将这个节点的子节点代替这个节点
#如果是有两个子节点的节点,从右子树找最小元素替代;或左子树找到最大元素替代。这样右子树的最小值和左子树的最大值一定是叶节点或只有一个子节点
def delete(x,BST):
if BST is None:
print("没找到元素")
elif x < BST.data:
BST.left = Delete(x,BST.left)
elif x > BST.data:
BST.right = Delete(x,BST.right)
else:
#如果有两个子节点,找右子树的最小值代替
if BST.left is not None and BST.right is not None:
temp = FindMin(BST.right)
BST.data = temp.data
BST.right = delete(temp.data,BST.right)
else:
temp = BST
#如果只有一个子节点,用子节点代替;如果是叶节点,删除
if BST.left is None:
BST = BST.right
elif BST.right is None
BST = BST.left
return BST
5. 平衡二叉树(AVL,Balanced Binary Tree)
平衡二叉树是一种搜索二叉树,满足搜索二叉树的性质
- 有关平衡的概念
- “平衡因子”(Balance Factor): B F = h L − h R BF = h_L - h_R BF=hL−hR,左子树和右子树的高度之差
- 平衡二叉树(Balanced Binary Tree)AVL树:任一节点左、右子树的高度差不超过1,
∣
B
F
(
T
)
∣
⩽
1
|BF(T)|\leqslant 1
∣BF(T)∣⩽1
对于图上3节点,左子树高度为2,右子树高度为0,相差2,因此不是平衡二叉树
- 平衡二叉树的高度
- 由于树节点的插入次序会导致不同的深度和平均查找长度ASL(查找效率);如果能让树平衡,可以使树高度降低,最低为 log 2 n \log_2 n log2n
- 高度为h时,若使节点数最少:
n
h
=
n
h
−
1
+
n
h
−
2
+
1
n_h = n_{h-1} + n_{h-2}+1
nh=nh−1+nh−2+1。
- 另 n h n_h nh为高度为h时的最少节点树
- 左子树和右子树的高度相差最多为1
- 左子树节点 + 右子树节点 + 根结点 = 整颗树的节点
5.1 平衡二叉树的调整
- 一棵平衡二叉树,新插入一个节点(麻烦节点)导致树的平衡被破坏;距离这个麻烦节点最近的平衡被破坏的节点,叫做发现者。
- 树调整时一定要保证左子树小于根结点,小于右子树,即保证仍然是一颗搜索树
- 右单旋(RR)
麻烦节点在被破坏节点的右子树的右子树上。
调整:把发现者A的右子节点B当作子树的根结点;把A变作B的左子树,把B的原左子树BL变为A节点的右子树。
- 左单旋(LL):
麻烦节点在被破环节点的左子树的左子树上
调整:用被破坏者的左子树代替被破坏者;把被破坏者作为其左子树的右子树(调整时考虑最下面的被破坏者,例如,B和A都被破坏,但是考虑移动B)
- 左-右双旋(LR):
破坏者在被破坏者的左子树的右子树上。
- 右-左双旋(RL):
破坏者在被破坏者的右子树的左子树上