forked from Jack-Lee-Hiter/AlgorithmsByPython
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bdcc80a
commit c25c85d
Showing
9 changed files
with
853 additions
and
102 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
# 构建二叉查找树(非平衡) | ||
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 | ||
|
||
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) | ||
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 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.rightChild = newRoot | ||
newRoot.rightChild = rotRoot | ||
rotRoot.parent = newRoot | ||
rotRoot.balanceFactor = rotRoot.balanceFactor + 1 - min(newRoot.balanceFactor, 0) | ||
newRoot.balanceFactor = newRoot.balanceFactor + 1 + max(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 __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 -= 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.hasLeftChild(): | ||
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(mytree[6]) | ||
print(mytree[2]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# 构建树实现堆 | ||
class BinHeap: | ||
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 += 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): | ||
i = len(alist) // 2 | ||
self.currentSize = len(alist) | ||
self.heapList = [0] + alist[:] | ||
while (i > 0): | ||
self.percDown(i) | ||
i = i - 1 | ||
return self.heapList | ||
|
||
H = BinHeap() | ||
print(H.buildHeap([9, 6, 5, 2, 3])) |
Oops, something went wrong.