myTree = [
'a', #根节点 myTree[0]
['b',#左子树 myTree[1]
['d',[],[]],
['e',[],[]]],
['c',#右子树 myTree[2]
['f',[],[]],
[]]
]
通过定义一系列函数来符注操作嵌套列表:
#创建仅有根节点的二叉树
def BinaryTree(r):
return [r,[],[]]
#将新节点插入树中作为其直接的左子节点(如果已有左子节点,则把原左子节点作为新插入节点的左子节点,新插入节点做直接的左子节点)
def insertLeft(root,newBranch):
t = root.pop(1)
if len(t) > 1:
root.insert(1,[newBranch,t,[]])
else:
root.insert(1,[newBranch,[],[]])
return root
#将新节点插入树中作为其直接的右子节点(如果已有右子节点,则把原右子节点作为新插入节点的右子节点,新插入节点做直接的右子节点)
def insertRight(root,newBranch):
t = root.pop(2)
if len(t) > 1:
root.insert(2,[newBranch,[],t])
else:
root.insert(2,[newBranch,[],[]])
return root
#获取根节点数据项
def getRootVal(root):
return root[0]
#更新根节点数据项
def setRootVal(root,newVal):
root[0] = newVal
#获取左子树
def getLeftChild(root):
return root[1]
#获取右子树
def getRightChild(root):
return root[2]
#应用
r = BinaryTree(3)
insertLeft(r, 4)
insertLeft(r, 5)
insertRight(r, 6)
insertRight(r, 7)
l = getLeftChild(r)
print(l)
setRootVal(l, 9)
print(r)
insertLeft(l, 11)
print(r)
print(getRightChild(getRightChild(r)))
[5, [4, [], []], []]
[3, [9, [4, [], []], []], [7, [], [6, [], []]]]
[3, [9, [11, [4, [], []], []], []], [7, [], [6, [], []]]]
[6, [], []]
class BinaryTree:
def __init__(self, rootObj):
self.key = rootObj #成员key保存根节点数据项
self.leftChild = None #成员leftChid/rightChild则保存指向左/右子树的引用(同样是BinaryTree对象)
self.rightChild = None
def insertLeft(self, newNode):
if self.leftChild == None:
self.leftChild = BinaryTree(newNode)
else:
t = BinaryTree(newNode)
t.leftChild = self.leftChild
self.leftChild = t
def insertRight(self, newNode):
if self.rightChild == None:
self.rightChild = BinaryTree(newNode)
else:
t = BinaryTree(newNode)
t.rightChild = self.rightChild
self.rightChild = t
def getRightChild(self):
return self.rightChild
def getLeftChild(self):
return self.leftChild
def setRootVal(self, obj):
self.key = obj
def getRootVal(self):
return self.key
r = BinaryTree('a')
r.insertLeft('b')
r.insertRight('c')
r.getRightChild().setRootVal('hello')
r.getLeftChild().insertRight('d')
树用于表示语言中的句子,可以分析句子的各种语法成分,对句子的各种成分进行处理
将表达式表示为树结构:叶节点保存操作数,内部节点保存操作符
表达式解析:从全括号表达式构建表达式解析树,利用表达式解析树对表达式求值,从表达式解析树恢复原表达式的字符串形式
建立表达式解析树思路
def buildPaeseTree(fpexp):
fplist = fpexp.split()#分割为token列表
pStack = Stack()
eTree = BinaryTree('')
pStack.push(eTree) #入栈下降
currentTree = eTree
for i in fplist:
#表达式开始
if i == '(':
currentTree.insertLeft('')
pStack.push(currentTree) #入栈下降
currentTree = currentTree.getLeftChild()
#操作数
elif i not in ['+', '-', '*', '/', ')']:
currentTree.setRootVal(int(i))
parent = pStack.pop() #出栈上升
currentTree = parent
#操作符
elif i in ['+', '-', '*', '/']:
currentTree.setRootVal(i)
currentTree.insertRight('')
pStack.push(currentTree) #入栈下降
currentTree = currentTree.getRightChild()
#表达式结束
elif i == ')':
currentTree = pStack.pop() #出栈上升
else:
raise ValueError
return eTree
pt = buildPaeseTree("((10 + 5) * 3)")
增强程序可读性operator模块,为我们提供了很多常用操作符的函数。当我们在字典中查找一个操作符时,相应的函数功能会被取回。因为这个取回的变量是一个函数,可以按通常调用的方式来调用它们,如函数名(变量1,变量2)。
import operator
print(operator.add)
print(operator.add(1,2))
op = operator.add
n = op(1,2)
print(n)
3
3
利用表达式解析树求值思路:
import operator
def evaluate(parseTree):
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv} #操作符字典,函数引用和操作符的映射
leftC = parseTree.getLeftChild() #缩小规模
rightC = parseTree.getRightChild()
if leftC and rightC:
fn = opers[parseTree.getRootVal()]
return fn(evaluate(leftC),evaluate(rightC)) #递归调用
else:
return parseTree.getRootVal() #基本结束条件
#前序遍历
def preorder(tree):
if tree:
print(tree.getRootVal())
preorder(tree.getLeftChild())
preorder(tree.getRightChild())
#中序遍历
def inorder(tree):
if tree != None:
inorder(tree.getLeftChild())
print(tree.getRootVal())
inorder(tree.getRightChild())
#后序遍历
def postorder(tree):
if tree != None:
postorder(tree.getLeftChild())
postorder(tree.getRightChild())
print(tree.getRootVal())
class BinaryTree:
def preorder(self):
print(self.key)
if self.leftChild:
self.leftChild.preorder()
if self.rightChild:
self.rightChild.preorder()
def inorder(self):
if self.leftChild:
self.leftChild.inorder()
print(self.key)
if self.rightChild:
self.rightChild.inorder()
def postorder(self):
if self.leftChild:
self.leftChild.postorder()
if self.rightChild:
self.rightChild.postorder()
print(self.key)
def postordereval(tree):
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv}
res1 = None
res2 = None
if tree:
res1 = postordereval(tree.getLeftChild()) #左子树
res2 = postordereval(tree.getRightChild()) #右子树
if res1 and res2: #根节点
return opers[tree.getRootVal()](res1, res2)
else:
return tree.getRootVal()
def printexp(tree):
sVal = ""
if tree:
sVal = '(' + printexp(tree.getLeftChild())
sVal = sVal + str(tree.getRootVal())
sVal = sVal + printexp(tree.getRightChild()) + ')'
return sVal
class BinHeap:
def __init__(self):
self.heapList = [0]
self.currentSize = 0
def insert(self, k):
self.heapList.append(k) #新key添加到列表末尾
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize) #新key上浮
def percUp(self, i):
while i // 2 > 0:
if self.heapList[i] < self.heapList[i//2]:
self.heapList[i],self.heapList[i//2] = self.heapList[i//2],self.heapList[i] #与父节点进行交换
i = i // 2
def delMin(self):
retval = self.heapList[1] #移走堆顶
self.heapList[1] = self.heapList[self.currentSize]
self.currentSize = self.currentSize - 1
self.heapList.pop()
self.percDown(1) #新项下沉
return retval
def percDown(self, i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
self.heapList[i],self.heapList[mc] = self.heapList[mc],self.heapList[i] #交换下沉
i = mc #沿着路径向下
def minChild(self, i):
if (i * 2 + 1) > self.currentSize: #唯一子节点
return i * 2
else:
if self.heapList[i * 2] < self.heapList[i * 2 + 1]: #左右子节点值比较,返回较小的
return i * 2
else:
return i * 2 + 1
def buildHeap(self, alist):
i = len(alist) // 2 #从最后节点的父节点开始,因为叶节点无需下沉
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
print(len(self.heapList),i)
while i > 0:
print(self.heapList, i)
self.percDown(i)
i = i - 1
print(self.heapList,i)
代码测试:
class BinHeap:
def __init__(self):
self.heapList = [0]
self.currentSize = 0
def insert(self, k):
self.heapList.append(k) #新key添加到列表末尾
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize) #新key上浮
def percUp(self, i):
while (i // 2) > 0:
if self.heapList[i] < self.heapList[i//2]:
self.heapList[i],self.heapList[i//2] = self.heapList[i//2],self.heapList[i] #与父节点进行交换
i = i // 2
def buildHeap(self, alist):
i = len(alist) // 2 #从最后节点的父节点开始,因为叶节点无需下沉
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
print(len(self.heapList),i)
while i > 0:
print(self.heapList, i)
self.percDown(i)
i = i - 1
print(self.heapList,i)
def delMin(self):
retval = self.heapList[1] #移走堆顶
self.heapList[1] = self.heapList[self.currentSize]
self.currentSize = self.currentSize - 1
self.heapList.pop()
self.percDown(1) #新项下沉
return retval
def percDown(self, i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
self.heapList[i],self.heapList[mc] = self.heapList[mc],self.heapList[i] #交换下沉
i = mc #沿着路径向下
def minChild(self, i):
if (i * 2 + 1) > self.currentSize: #唯一子节点
return i * 2
else:
if self.heapList[i * 2] < self.heapList[i * 2 + 1]: #左右子节点值比较,返回较小的
return i * 2
else:
return i * 2 + 1
alist = [3,1,4,9,6,7,5,8,2,10]
h = BinHeap()
h.buildHeap(alist)
h.insert(2)
print('-------------------------------------')
print(h.heapList)
print(h.delMin())
print(h.heapList)
11 5
[0, 3, 1, 4, 9, 6, 7, 5, 8, 2, 10] 5
[0, 3, 1, 4, 9, 6, 7, 5, 8, 2, 10] 4
[0, 3, 1, 4, 2, 6, 7, 5, 8, 9, 10] 3
[0, 3, 1, 4, 2, 6, 7, 5, 8, 9, 10] 2
[0, 3, 1, 4, 2, 6, 7, 5, 8, 9, 10] 1
[0, 1, 2, 4, 3, 6, 7, 5, 8, 9, 10] 0
-------------------------------------
[0, 1, 2, 4, 3, 2, 7, 5, 8, 9, 10, 6]
1
[0, 2, 2, 4, 3, 6, 7, 5, 8, 9, 10]
def big_endian(arr,start,end):
root=start
child=root*2+1 #左孩子
while child<=end:
#孩子比最后一个节点还大,也就意味着最后一个叶子节点了,就得跳出去一次循环,已经调整完毕
if child+1<=end and arr[child]<arr[child+1]:
#为了始终让其跟子元素的较大值比较,如果右边大就左换右,左边大的话就默认
child+=1
if arr[root]<arr[child]:
#父节点小于子节点直接交换位置,同时坐标也得换,这样下次循环可以准确判断:是否为最底层,
#是不是调整完毕
arr[root],arr[child]=arr[child],arr[root]
root=child
child=root*2+1
else:
break
def heap_sort(arr): #无序区大根堆排序
first=len(arr)//2 - 1
for start in range(first,-1,-1):
#从下到上,从左到右对每个节点进行调整,循环得到非叶子节点
big_endian(arr,start,len(arr)-1) #去调整所有的节点
for end in range(len(arr)-1,0,-1):
arr[0],arr[end]=arr[end],arr[0] #顶部尾部互换位置
big_endian(arr,0,end-1) #重新调整子节点的顺序,从顶开始调整
return arr
def main():
l=[3,1,4,9,6,7,5,8,2,10]
print(heap_sort(l))
if __name__ == "__main__":
main()
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
class BinarySearchTree:
def __init__(self):
self.root = None
self.size = 0
def length(self):
return self.size
def __len__(self): #可以使用python的内置方法求长度了
return self.size
def __iter__(self): #迭代
return self.root.__iter__()
class TreeNode:
def __init__(self, key, val, left = None, right = None, parent = None):#可选参数的使用
self.key = key #键
self.payload = val #值
self.leftChild = left #左子节点
self.rightChild = right #右子节点
self.parent = parent #父节点
def hasLeftChild(self):
return self.leftChild
def hasRightChild(self):
return self.rightChild
def isLeftChild(self):
return self.parent and self.parent.leftChild == self
def isRightChild(self):
return self.parent and self.parent.rightChild == self
def isRoot(self):
return not self.parent
def isLeaf(self):
return not (self.rightChild or self.leftChild)
def hasAnyChildren(self):
return self.rightChild or self.leftChild
def hasBothChildren(self):
return self.rightChild and seld.leftChild
def replaceNodeData(self, key, value, lc, rc):
self.key = key
self.payload = value
self.leftChild = lc
self.rightChild = rc
if self.hasLeftChild():
self.leftChild.parent = self
if self.hasRightChild():
self.rightChild.parent = self
def put(self, key, val):
if self.root:
self._put(key, val, self,root)
else:
self.root = TreeNode(key, val)
self.size = self.size + 1
def _put(self, key, val, currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key, val, currentNode.leftChild) #递归左子树
else:
currentNode.leftChild = TreeNode(key, val, parent = currentNode)
else:
if currentNode.hasRightChild():
self._put(key, val, currentNode.rightChild) #递归右子树
else:
currentNode.rightChild = TreeNode(key, val, parent = currentNode)
def __setitem__(self, k, v):
self.put(k, v)
def get(self, key):
if self.root:
res = self._get(key, self.root) #递归函数
if res: #找到节点
return res.payload
else:
return None
else:
return None
def _get(self, key, currentNode): #返回一个TreeNode给get
if not currentNode:
return None
elif currentNode.key == key:
return currentNode
elif key < currentNode.key:
return self._get(key, currentNode.leftChild)
else:
return self._get(key, currentNode.rightChild)
def __getitem__(self, key):
return self.get(key)
def __contains__(self, key):
if self._get(key, self,root):
return True
else:
return False
def __iter__(self):
if self:
if self.hasLeftChild():
for elem in self.leftChild:
yield elem
yield self.key
if self.hasRightChild():
for elem in self.rightChild:
yield elem
def delete(self, key):
if self.size > 1:
nodeToRemove = self._get(key, self.root)
if nodeToRemove:
self.remove(nodeToRemove)
self.size = self.size - 1
else:
raise KeyError('Error, key not in tree')
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = self.size - 1
else:
raise KeyError('Error, key not in tree')
def __delitem(self, key):
self.delete(key)
BinarySearchTree.remove()方法:删除节点后,要求仍保持BinarySearchTree的性质,分为以下3种情形:
def remove(self,currentNode):
if currentNode.isLeaf(): #这个节点没有子节点
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
else:
currentNode.parent.rightChild = None
elif currentNode.hasBothChildren(): #这个节点有两个子节点
succ = currentNode.findSuccessor()
succ.spliceOut()
currentNode.key = succ.key
currentNode.payload = succ.payload
else: #这个节点有一个子节点
if currentNode.hasLeftChild():
if currentNode.isLeftChild(): #左左:当前节点的左子节点成为当前节点父节点的新的左子节点
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
elif currentNode.isRightChild(): #右左:当前节点的左子节点成为当前节点父节点的新的右子节点
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
else:
if currentNode.isLeftChild(): #左右:当前节点的右子节点成为当前节点父节点的新的左子节点
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.rightChild
elif currentNode.isRightChild(): #右右:当前节点的右子节点成为当前节点父节点的新的右子节点
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.rightChild
else:
currentNode.replaceNodeData(currentNode.rightChild.key,
currentNode.rightChild.payload,
currentNode.rightChild.leftChild,
currentNode.rightChild.rightChild)
def findSuccessor(self):
succ = None
if self.hasRightChild():
succ = self.rightChild.findMin()
else: #目前不会遇到:因为当前要找后继的节点,其右子树肯定存在
if self.parent:
if self.isLeftChild():
succ = self.parent
else:
self.parent.rightChild = None
succ = self.parent.findSuccessor()
self.parent.rightChild = self
return succ
def findMin(self):
current = self
while current.hasRightChild():
current = current.leftChild #到左下角
return current
def spliceOut(self):
if self.isLeaf(): #摘出叶节点
if self.isLeftChild():
self.parent.leftChild = None
else:
self.parent.rightChild = None
elif self.hasAnyChildren():
if self.hasLeftChild(): #目前不会遇到:因为左右子树肯定存在
if self.isLeftChild():
self.parent.leftChild = self.leftChild
else:
self.parent.rightChild = self.leftChild
self.leftChild.parent = self.parent
else:
if self.isLeftChild(): #摘出带右子节点的节点
self.parent.leftChild = self.rightChild
else:
self.parent.rightChild = self.rightChild
self.rightChild.parent = self.parent
全部代码:
class TreeNode:
def __init__(self,key,val,left=None,right=None,parent=None):
self.key = key
self.payload = val
self.leftChild = left
self.rightChild = right
self.parent = parent
def hasLeftChild(self):
return self.leftChild
def hasRightChild(self):
return self.rightChild
def isLeftChild(self):
return self.parent and self.parent.leftChild == self
def isRightChild(self):
return self.parent and self.parent.rightChild == self
def isRoot(self):
return not self.parent
def isLeaf(self):
return not (self.rightChild or self.leftChild)
def hasAnyChildren(self):
return self.rightChild or self.leftChild
def hasBothChildren(self):
return self.rightChild and self.leftChild
def replaceNodeData(self,key,value,lc,rc):
self.key = key
self.payload = value
self.leftChild = lc
self.rightChild = rc
if self.hasLeftChild():
self.leftChild.parent = self
if self.hasRightChild():
self.rightChild.parent = self
def __iter__(self):
if self:
if self.hasLeftChild():
for elem in self.leftChiLd:
yield elem
yield self.key
if self.hasRightChild():
for elem in self.rightChild:
yield elem
class BinarySearchTree:
def __init__(self):
self.root = None
self.size = 0
def length(self):
return self.size
def __len__(self):
return self.size
def __iter__(self):
return self.root.__iter__()
def put(self,key,val):
if self.root:
self._put(key,val,self.root)
else:
self.root = TreeNode(key,val)
self.size = self.size + 1
def _put(self,key,val,currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key,val,currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key,val,parent=currentNode)
else:
if currentNode.hasRightChild():
self._put(key,val,currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key,val,parent=currentNode)
def __setitem__(self,k,v):
self.put(k,v)
def get(self,key):
if self.root:
res = self._get(key,self.root)
if res:
return res.payload
else:
return None
else:
return None
def _get(self,key,currentNode):
if not currentNode:
return None
elif currentNode.key == key:
return currentNode
elif key < currentNode.key:
return self._get(key,currentNode.leftChild)
else:
return self._get(key,currentNode.rightChild)
def __getitem__(self,key):
return self.get(key)
def __contains__(self,key):
if self._get(key,self.root):
return True
else:
return False
def delete(self,key):
if self.size > 1:
nodeToRemove = self._get(key,self.root)
if nodeToRemove:
self.remove(nodeToRemove)
self.size = self.size-1
else:
raise KeyError('Error, key not in tree')
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = self.size - 1
else:
raise KeyError('Error, key not in tree')
def __delitem__(self,key):
self.delete(key)
def spliceOut(self):
if self.isLeaf():
if self.isLeftChild():
self.parent.leftChild = None
else:
self.parent.rightChild = None
elif self.hasAnyChildren():
if self.hasLeftChild():
if self.isLeftChild():
self.parent.leftChild = self.leftChild
else:
self.parent.rightChild = self.leftChild
self.leftChild.parent = self.parent
else:
if self.isLeftChild():
self.parent.leftChild = self.rightChild
else:
self.parent.rightChild = self.rightChild
self.rightChild.parent = self.parent
def findSuccessor(self):
succ = None
if self.hasRightChild():
succ = self.rightChild.findMin()
else: #目前不会遇到:因为当前要找后继的节点,其右子树肯定存在
if self.parent:
if self.isLeftChild():
succ = self.parent
else:
self.parent.rightChild = None
succ = self.parent.findSuccessor()
self.parent.rightChild = self
return succ
def findMin(self):
current = self
while current.hasRightChild():
current = current.leftChild #到左下角
return current
def remove(self,currentNode):
if currentNode.isLeaf(): #leaf
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
else:
currentNode.parent.rightChild = None
elif currentNode.hasBothChildren(): #interior
succ = currentNode.findSuccessor()
succ.spliceOut()
currentNode.key = succ.key
currentNode.payload = succ.payload
else: # this node has one child
if currentNode.hasLeftChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
elif currentNode.isRightChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
else:
if currentNode.isLeftChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.rightChild
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.rightChild
else:
currentNode.replaceNodeData(currentNode.rightChild.key,
currentNode.rightChild.payload,
currentNode.rightChild.leftChild,
currentNode.rightChild.rightChild)
mytree = BinarySearchTree()
mytree[3]="red"
mytree[4]="blue"
mytree[6]="yellow"
mytree[2]="at"
print(3 in mytree)
print(mytree[6])
del mytree[2]
print(mytree[2])
for key in mytree:
print(key,mytree[key])
True
yellow
None
3 red
4 blue
6 yellow
向AVL树插入一个新key,如何保持AVL树的平衡性质?
def _put(self, key, val, currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key, val, currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key, val, parent = currentNode)
self.updateBalance(currentNode.leftChild) #调整因子
else:
if currentNode.hasRightChild():
self._put(key, val, currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key, val, parent = currentNode)
self.updateBalance(currentNode.rightChild) #调整因子
def updateBalance(self, node):
if node.balanceFactor > 1 or node.balanceFactor < -1:
self.rebalance(node) #重新平衡
return
if node.parent != Node:
if node.isLeftChild():
node.parent.balanceFactor += 1
elif node.isRightChild():
node.parent.balanceFactor -= 1
if node.parent.balanceFactor != 0: #调整父节点因子
self.updateBalance(node.parent)
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)
def rotateRight(self,rotRoot):
newRoot = rotRoot.leftChild
rotRoot.leftChild = newRoot.rightChild
if newRoot.rightChild != None:
newRoot.rightChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isRightChild():
rotRoot.parent.rightChild = newRoot
else:
rotRoot.parent.leftChild = newRoot
newRoot.rightChild = rotRoot
rotRoot.parent = newRoot
rotRoot.balanceFactor = rotRoot.balanceFactor - 1 - max(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor - 1 + min(rotRoot.balanceFactor, 0)
AVL树旋转更复杂的情形:
def rebalance(self, node):
if node.balanceFactor < 0: #右重需要左旋
if node.rightChild.balanceFactor > 0:
#Do an LR Rotation
self.rotateRight(node.rightChild) #右子节点左重先右旋
self.rotateLeft(node)
else:
#single left
self.rotateLeft(node)
elif node.balanceFactor > 0: #左重需要右旋
if node.leftChild.balanceFactor < 0:
#Do an RL Rotation
self.rotateLeft(node.leftChild) #左子节点右重先左旋
self.rotateRight(node)
else:
#single right
self.rotateRight(node)
class AVLTree(BinarySearchTree):
def _put(self,key,val,currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key,val,currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key,val,parent=currentNode)
self.updateBalance(currentNode.leftChild)
else:
if currentNode.hasRightChild():
self._put(key,val,currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key,val,parent=currentNode)
self.updateBalance(currentNode.rightChild)
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
if node.parent.balanceFactor != 0:
self.updateBalance(node.parent)
def rebalance(self,node):
if node.balanceFactor < 0:
if node.rightChild.balanceFactor > 0:
# Do an LR Rotation
self.rotateRight(node.rightChild)
self.rotateLeft(node)
else:
# single left
self.rotateLeft(node)
elif node.balanceFactor > 0:
if node.leftChild.balanceFactor < 0:
# Do an RL Rotation
self.rotateLeft(node.leftChild)
self.rotateRight(node)
else:
# single right
self.rotateRight(node)
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)
def rotateRight(self,rotRoot):
newRoot = rotRoot.leftChild
rotRoot.leftChild = newRoot.rightChild
if newRoot.rightChild != None:
newRoot.rightChild.parent = rotRoot
newRoot.parent = rotRoot.parent
if rotRoot.isRoot():
self.root = newRoot
else:
if rotRoot.isRightChild():
rotRoot.parent.rightChild = newRoot
else:
rotRoot.parent.leftChild = newRoot
newRoot.rightChild = rotRoot
rotRoot.parent = newRoot
rotRoot.balanceFactor = rotRoot.balanceFactor - 1 - max(newRoot.balanceFactor, 0)
newRoot.balanceFactor = newRoot.balanceFactor - 1 + min(rotRoot.balanceFactor, 0)