6.Python数据结构与算法分析课后习题(第二版)__chapter6
Python数据结构与算法分析第二版课后习题
·
chapter6_answer
- 一、讨论题
- 二、编程练习
-
- 1.扩展buildParseTree方法,使其能够处理字符间没有空格的数字表达式。
- 2.修改buildParseTree和evaluate,使它们支持逻辑运算符(and、or、not)。注意,not是一元运算符,这会让代码有点复杂。
- 3.使用findSuccessor方法,写一个非递归的二叉搜索树中序遍历方法。
- 4.修改二叉搜索树的实现代码,从而实现线索二叉搜索树。为线索二叉搜索树写一个非递归的中序遍历方法。线索二叉搜索树为其中的每个节点都维护者指向后继节点的引用。
- 5.修改二叉搜索树的实现代码,以正确处理重复的键。也就是说,如果键已在树中,就替换有效载荷,而不是用同一个键插入一个新节点。
- 6.创建限定大小的二叉堆。也就是说,堆只保持n个最重要的元素。如果堆的大小超过了n,就会舍弃最不重要的元素。
- 7.整理printexp函数,去掉数字周围多余的括号。
- 8.使用buildHeap方法,针对列表写一个时间复杂度为 O ( l o g n ) O(logn) O(logn)的排序函数。
- 9.写一个函数,以数学表达式解析树为参数,计算各变量的导数。
- 10.将二叉树实现为最大堆。
- 11.使用BinaryHeap类。实现一个叫做PriorityQueue的新类。为PriorityQueue类实现构造方法,以及enqueue方法和dequeue方法。
- 12.实现AVL树的delete方法。
- 三、总结
一、讨论题
略
二、编程练习
1.扩展buildParseTree方法,使其能够处理字符间没有空格的数字表达式。
2.修改buildParseTree和evaluate,使它们支持逻辑运算符(and、or、not)。注意,not是一元运算符,这会让代码有点复杂。
from chapter3.stack import Stack
from chapter6.BinaryTree2 import BinaryTree
import operator
def buildParseTree2(fpexp):
fplist1 = fpexp.split()
fplist = []
for i in fplist1:
if i in ['and', 'not', 'or']:
fplist.append(i)
elif i == '(not':
fplist.append('not')
else:
for j in i:
if j == 'n':
fplist.append('not')
break
else:
fplist.append(j)
pStack = Stack()
eTree = BinaryTree('')
pStack.push(eTree)
currentTree = eTree
currentTree.setRootVal(eval(fpexp))
for i in fplist:
if i == '(':
currentTree.insertLeft('')
pStack.push(currentTree)
currentTree = currentTree.getLeftChild()
elif i not in '+-*/)' and i not in ['and', 'or', 'not']:
currentTree.setRootVal(eval(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()
elif i in ['and', 'or', 'not']:
currentTree.setRootVal(i)
currentTree.insertRight('')
pStack.push(currentTree)
currentTree = currentTree.getRightChild()
else:
raise ValueError('Unknown Operator:' + i)
return eTree
def evaluate(parseTree):
opers = {'+':operator.add, '-':operator.sub, '*':operator.mul,
'/':operator.truediv, 'and':fn_and, 'or':fn_or,
'not':fn_not}
leftC = parseTree.getLeftChild()
rightC = parseTree.getRightChild()
if parseTree.getRootVal() == 'not':
fn = opers[parseTree.getRootVal()]
return fn(rightC)
else:
if leftC and rightC:
fn = opers[parseTree.getRootVal()]
return fn(evaluate(leftC), evaluate(rightC))
else:
return parseTree.getRootVal()
def fn_and(left, right):
return left and right
def fn_or(left, right):
return left or right
def fn_not(right):
return not right
if __name__ == '__main__':
tree = buildParseTree2('((1+0) or (not 0))')
print(evaluate(tree))
3.使用findSuccessor方法,写一个非递归的二叉搜索树中序遍历方法。
4.修改二叉搜索树的实现代码,从而实现线索二叉搜索树。为线索二叉搜索树写一个非递归的中序遍历方法。线索二叉搜索树为其中的每个节点都维护者指向后继节点的引用。
5.修改二叉搜索树的实现代码,以正确处理重复的键。也就是说,如果键已在树中,就替换有效载荷,而不是用同一个键插入一个新节点。
from chapter6.BinarySearchTree import TreeNode
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, value):
if self.root:
self._put(key, value, self.root)
else:
self.root = TreeNode(key, value)
self.size = self.size + 1
def _put(self, key, value, currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key, value, currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key, value, parent=currentNode)
currentNode.leftChild.succ = currentNode
if currentNode.parent:
beginNode = currentNode.parent
while beginNode:
if beginNode.findSuccessor() == currentNode.leftChild:
beginNode.succ = currentNode.leftChild
beginNode = beginNode.parent
elif key == currentNode.key:
currentNode.payload = value
else:
if currentNode.hasRightChild():
self._put(key, value, currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key, value, parent=currentNode)
currentNode.succ = currentNode.rightChild
if currentNode.rightChild.findSuccessor():
currentNode.rightChild.succ = currentNode.rightChild.findSuccessor()
def __setitem__(self, key, value):
self.put(key, value)
def get(self, key):
if self.root:
res = self._get(key, self.root)
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 -= 1
else:
raise KeyError('Error, key not in tree')
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = 0
else:
raise KeyError('Error, key not in tree')
def remove(self, currentNode):
if currentNode.isLeaf():
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
else:
currentNode.parent.rightChild = None
elif currentNode.hasLeftChild() and not currentNode.hasRightChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
elif currentNode.hasRightChild() and not currentNode.hasLeftChild():
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.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
else:
succ = currentNode.findSuccessor()
succ.spliceOut()
currentNode.key = succ.key
currentNode.payload = succ.payload
def inorder(self):
currentNode = self.root
while currentNode:
beginNode = currentNode
currentNode = currentNode.leftChild
while beginNode.findSuccessor():
print(beginNode.key)
beginNode = beginNode.findSuccessor()
print(beginNode.key)
def inorder2(self):
currentNode = self.root
while currentNode:
beginNode = currentNode
currentNode = currentNode.leftChild
while beginNode.succ:
print(beginNode.key)
beginNode = beginNode.succ
print(beginNode.key)
def __delitem__(self, key):
self.delete(key)
if __name__ == '__main__':
tree = BinarySearchTree()
tree.put(2, 0)
tree.put(7, 0)
tree.put(1, 0)
tree.put(3, 0)
tree.put(0, 0)
tree.put(0, 0)
tree.inorder2()
6.创建限定大小的二叉堆。也就是说,堆只保持n个最重要的元素。如果堆的大小超过了n,就会舍弃最不重要的元素。
class BinaryHeap:
def __init__(self, maxsize):
self.heapList = [0]
self.currentSize = 0
self.maxsize = maxsize
def percUp(self, i):
while i // 2 > 0:
if self.heapList[i] < self.heapList[i // 2]:
temp = self.heapList[i // 2]
self.heapList[i // 2] = self.heapList[i]
self.heapList[i] = temp
i = i // 2
def insert(self, k):
self.heapList.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
def percDown(self, i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
temp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = temp
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 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 buildHeap(self, alist):
if len(alist) > self.maxsize:
alist = alist[:self.maxsize]
i = len(alist) // 2
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
while (i > 0):
self.percDown(i)
i -= 1
if __name__ == '__main__':
heap = BinaryHeap(10)
alist = [11, 5, 9, 21, 17, 19, 18, 27, 14, 33, 90, 88]
heap.buildHeap(alist)
print(heap.heapList)
7.整理printexp函数,去掉数字周围多余的括号。
def printexp(tree):
sVal = ''
if tree:
if tree.leftChild == None and tree.rightChild == None:
sVal = sVal + str(tree.getRootVal())
else:
sVal = '(' + printexp(tree.getLeftChild())
sVal = sVal + str(tree.getRootVal())
sVal = sVal + printexp(tree.getRightChild()) + ')'
return sVal
if __name__ == '__main__':
from chapter6.BinaryTree2 import BinaryTree
x = BinaryTree('*')
x.insertLeft('+')
l = x.getLeftChild()
l.insertLeft(4)
l.insertRight(5)
x.insertRight(7)
print(printexp(x))
8.使用buildHeap方法,针对列表写一个时间复杂度为 O ( l o g n ) O(logn) O(logn)的排序函数。
class BinaryHeap:
def __init__(self, maxsize):
self.heapList = [0]
self.currentSize = 0
self.maxsize = maxsize
def percUp(self, i):
while i // 2 > 0:
if self.heapList[i] < self.heapList[i // 2]:
temp = self.heapList[i // 2]
self.heapList[i // 2] = self.heapList[i]
self.heapList[i] = temp
i = i // 2
def insert(self, k):
self.heapList.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
def percDown(self, i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
temp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = temp
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 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 buildHeap(self, alist):
if len(alist) > self.maxsize:
alist = alist[:self.maxsize]
i = len(alist) // 2
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
while (i > 0):
self.percDown(i)
i -= 1
def sort(alist):
heap = BinaryHeap(10)
blist = [0]
heap.buildHeap(alist)
for i in range(1, len(alist) + 1):
if heap.currentSize > 0:
blist += [heap.heapList[1]]
heap.buildHeap(heap.heapList[2:])
print(blist)
if __name__ == '__main__':
alist = [9, 6, 5, 2, 3]
sort(alist)
9.写一个函数,以数学表达式解析树为参数,计算各变量的导数。
说实话我没看懂这个题目,计算变量的导数,所以数学表达式是含有xyz吗???在网上搜到一个和这个题目类似的,但我的python版本太低导入不了其中的一个包,我就没有试…大家可以下载下来自己跑一下。
参考链接:
http://git.oschina.net/yangtf/python_exp link
10.将二叉树实现为最大堆。
class BinaryMaxHeap:
def __init__(self):
self.heapList = [0]
self.currentSize = 0
def percUp(self, i):
while i // 2 > 0:
if self.heapList[i] > self.heapList[i // 2]:
temp = self.heapList[i // 2]
self.heapList[i // 2] = self.heapList[i]
self.heapList[i] = temp
i = i // 2
def insert(self, k):
self.heapList.append(k)
self.currentSize = self.currentSize + 1
self.percUp(self.currentSize)
def percDown(self, i):
while (i * 2) <= self.currentSize:
mc = self.maxChild(i)
if self.heapList[i] < self.heapList[mc]:
temp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = temp
i = mc
def maxChild(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 delMax(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 buildHeap(self, alist):
i = len(alist) // 2
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
while (i > 0):
self.percDown(i)
i -= 1
if __name__ == '__main__':
heap = BinaryMaxHeap()
alist = [11, 5, 9, 21, 17, 19, 18, 27, 14, 33, 90, 88]
heap.buildHeap(alist)
print(heap.heapList)
heap.delMax()
print(heap.heapList)
11.使用BinaryHeap类。实现一个叫做PriorityQueue的新类。为PriorityQueue类实现构造方法,以及enqueue方法和dequeue方法。
from chapter6.BinaryHeap import BinaryHeap
class PriorityQueue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.append(item)
heap = BinaryHeap()
heap.buildHeap(self.items)
self.items = heap.heapList[1:]
def dequeue(self):
return self.items.pop(0)
def size(self):
return len(self.items)
if __name__ == '__main__':
q = PriorityQueue()
q.enqueue(5)
q.enqueue(2)
q.enqueue(3)
q.enqueue(6)
q.enqueue(1)
print(q.items)
q.dequeue()
print(q.items)
12.实现AVL树的delete方法。
实现AVL的delete方法,要更新平衡因子,然后再平衡。
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, value):
if self.root:
self._put(key, value, self.root)
else:
self.root = TreeNode(key, value)
self.size = self.size + 1
def _put(self, key, value, currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key, value, currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key, value, parent=currentNode)
currentNode.leftChild.succ = currentNode
if currentNode.parent:
beginNode = currentNode.parent
while beginNode:
if beginNode.findSuccessor() == currentNode.leftChild:
beginNode.succ = currentNode.leftChild
beginNode = beginNode.parent
elif key == currentNode.key:
currentNode.payload = value
else:
if currentNode.hasRightChild():
self._put(key, value, currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key, value, parent=currentNode)
currentNode.succ = currentNode.rightChild
if currentNode.rightChild.findSuccessor():
currentNode.rightChild.succ = currentNode.rightChild.findSuccessor()
def __setitem__(self, key, value):
self.put(key, value)
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 -= 1
else:
raise KeyError('Error, key not in tree')
elif self.size == 1 and self.root.key == key:
self.root = None
self.size = 0
else:
raise KeyError('Error, key not in tree')
def remove(self, currentNode):
if currentNode.isLeaf():
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
else:
currentNode.parent.rightChild = None
elif currentNode.hasLeftChild() and not currentNode.hasRightChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
elif currentNode.hasRightChild() and not currentNode.hasLeftChild():
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.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
else:
succ = currentNode.findSuccessor()
succ.spliceOut()
currentNode.key = succ.key
currentNode.payload = succ.payload
def inorder(self):
currentNode = self.root
while currentNode:
beginNode = currentNode
currentNode = currentNode.leftChild
while beginNode.findSuccessor():
print(beginNode.key, beginNode.balanceFactor)
beginNode = beginNode.findSuccessor()
print(beginNode.key, beginNode.balanceFactor)
def inorder2(self):
currentNode = self.root
while currentNode:
beginNode = currentNode
currentNode = currentNode.leftChild
while beginNode.succ:
print(beginNode.key)
beginNode = beginNode.succ
print(beginNode.key)
def __delitem__(self, key):
self.delete(key)
class TreeNode:
def __init__(self, key, val, left=None, right=None, parent=None, succ=None, balanceFactor=0):
self.key = key
self.payload = val
self.leftChild = left
self.rightChild = right
self.parent = parent
self.succ = succ
self.balanceFactor = balanceFactor
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.leftChild and self.rightChild
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 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.hasLeftChild():
current = current.leftChild
return current
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 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 spliceOut2(self):
if self.isLeaf():
if self.isLeftChild():
self.parent.leftChild = None
self.parent.balanceFactor -= 1
else:
self.parent.rightChild = None
self.parent.balanceFactor += 1
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
self.parent.balanceFactor -= 1
else:
self.parent.rightChild = self.rightChild
self.parent.balanceFactor += 1
self.rightChild.parent = self.parent
class AVL(BinarySearchTree):
def _put(self, key, value, currentNode):
if key < currentNode.key:
if currentNode.hasLeftChild():
self._put(key, value, currentNode.leftChild)
else:
currentNode.leftChild = TreeNode(key, value, parent=currentNode)
self.updateBalance(currentNode.leftChild)
else:
if currentNode.hasRightChild():
self._put(key, value, currentNode.rightChild)
else:
currentNode.rightChild = TreeNode(key, value, 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 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.isLeftChild():
rotRoot.parent.leftChild = newRoot
else:
rotRoot.parent.rightChild = 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)
def rebalance(self, node):
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)
def updateBalance2(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.updateBalance2(node.parent)
def delete1(self, key):
if self.size > 1:
nodeToRemove = self._get(key, self.root)
if nodeToRemove:
self.remove1(nodeToRemove)
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 = 0
else:
raise KeyError('Error, key not in tree')
def remove1(self, currentNode):
if currentNode.isLeaf():
if currentNode == currentNode.parent.leftChild:
currentNode.parent.leftChild = None
currentNode.parent.balanceFactor -= 1
else:
currentNode.parent.rightChild = None
currentNode.parent.balanceFactor += 1
self.updateBalance2(currentNode.parent)
elif currentNode.hasLeftChild() and not currentNode.hasRightChild():
if currentNode.isLeftChild():
currentNode.leftChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.leftChild
currentNode.parent.balanceFactor -= 1
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.leftChild
currentNode.parent.balanceFactor += 1
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
self.updateBalance2(currentNode.parent)
elif currentNode.hasRightChild() and not currentNode.hasLeftChild():
if currentNode.isLeftChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.leftChild = currentNode.rightChild
currentNode.parent.balanceFactor -= 1
elif currentNode.isRightChild():
currentNode.rightChild.parent = currentNode.parent
currentNode.parent.rightChild = currentNode.rightChild
currentNode.parent.balanceFactor += 1
else:
currentNode.replaceNodeData(currentNode.leftChild.key,
currentNode.leftChild.payload,
currentNode.leftChild.leftChild,
currentNode.leftChild.rightChild)
self.updateBalance2(currentNode.parent)
else:
succ = currentNode.findSuccessor()
succ.spliceOut2()
self.updateBalance2(currentNode)
currentNode.key = succ.key
currentNode.payload = succ.payload
if __name__ == '__main__':
tree = AVL()
tree.put(2, 0)
tree.put(7, 0)
tree.put(1, 0)
tree.put(3, 0)
tree.put(0, 0)
tree.inorder()
node = tree._get(7, tree.root)
print('xxxx', tree.root.key, tree._get(1, tree.root).balanceFactor,
tree._get(3, tree.root).balanceFactor,
tree._get(7, tree.root).balanceFactor,
tree._get(0, tree.root).balanceFactor, )
tree.delete1(3)
tree.inorder()
print('xxxx', tree.root.key, tree._get(1, tree.root).balanceFactor,
tree._get(2, tree.root).balanceFactor,
tree._get(7, tree.root).balanceFactor,
tree._get(0, tree.root).balanceFactor, )
三、总结
主要学习了
1.用python表达树的两种方法,
2.二叉搜索树,AVL树,
3.最大堆,最小堆等。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)