數據結構學習筆記21(北大公開課)目錄
樹結構
一、知識概覽
本章主要講AVL樹及其實現,並對樹結構和ADT MAP進行小結。
1.1 AVL樹
1.2 AVL樹的實現
一些重點及公式推導過程:
1.3 AVL樹結語
1.4 樹結構小結
1.5 ADT MAP小結
二、AVL樹代碼實現
2.1 put方法
# AVL樹的實現:put方法
def _put(self, key, val, currentNode):
'''如果key比currentNode小,那麼_put到左子樹,如果沒有左子樹,那麼key就成爲左子節點,反之亦然'''
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key, val, currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key, val, parent=currentNode)
# 調整因子
self.updateBalance(currentNode.left)
else:
if currentNode.hasRightChild():
self._put(key, val, currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key, val, parent=currentNode)
self.updateBalance(currentNode.right)
2.2 UpdateBalance方法
# UpdateBalance方法
def updateBalance(self, node):
if node.balanceFactor > 1 or node.balanceFactor < -1:
self.rebalance(node) # 重新平衡
return
# 如果有父節點,看是父節點的左子節點還是右子節點,調整平衡因子
if node.parent != None:
if node.isLeftChild():
node.parent.balanceFactor += 1
elif node.isRightChild():
node.parent.balanceFactor -= 1
# 判斷父節點是否調整爲0了,只要不爲0,就要調整父節點的平衡因子
if node.parent.balanceFactor != 0:
self.updateBalance(node.parent)
2.3 左旋方法
# rotateLeft方法
def rotateLeft(self, rotRoot):
newRoot = rotRoot.rightChild
# 把舊的根節點的右子節點指向新的根節點的左子節點
rotRoot.rightChild = newRoot.leftChild
if newRoot.leftChild != None:
newRoot.leftChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isLeftChild():
rotRoot.parent.leftChild = newRoot
else:
rotRoot.parent.rightChild = newRoot
newRoot.leftChild = rotRoot
rotRoot.parent = newRoot
# 僅有舊的根和新的根這兩個節點要調整平衡因子
rotRoot.balanceFactor = rotRoot.balanceFactor + 1 - min(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor + 1 + max(rotRoot.balanceFactor, 0)
右旋類似。
2.4 重新平衡方法
# rebalance方法
def rebalance(self, node):
# 如果一個節點平衡因子小於0,右重需左旋
if node.balanceFactor < 0:
# 檢查右子節點是否左重,左重先右旋再左旋
if node.rightChild.balanceFactor > 0:
self.rotateRight(node.rightChild)
self.rotateLeft(node)
else:
self.rotateLeft(node)
elif node.balanceFactor > 0:
# 檢查左子節點是否右重,右重先左旋再右旋
if node.leftChild.balanceFactor > 0:
self.rotateLeft(node.leftChild)
self.rotateRight(node)
else:
self.rotateRight(node)