class AbstractBinarySearchTree(object): def __init__(self, pHead): self.root = pHead self.size = 0 def createNode(self, value, parent, left, right): self.newNode = withParentNode(value) self.newNode.parent = parent self.newNode.left = left self.newNode.right = right return self.newNode def search(self, element): node = self.root while node is not None and node.value is not None and node.value != element: if element < node.value: node = node.left else: node = node.right return node def insert(self, element): if self.root is None: self.root = self.createNode(element, None, None, None) self.size += 1 return self.root insertParentNode = None searchTempNode = self.root while searchTempNode is not None and searchTempNode.value is not None: insertParentNode = searchTempNode if element < searchTempNode.value: searchTempNode = searchTempNode.left else: searchTempNode = searchTempNode.right newNode = self.createNode(element, insertParentNode, None, None) if insertParentNode.value > newNode.value: insertParentNode.left = newNode else: insertParentNode.right = newNode self.size += 1 return newNode def delete(self, element): # 如果该节点既有左子树,又有右子树,则找到该节点右子树的最左节点,来代替它的位置。如果最左节点有右子树,则挂在该节点原来的位置 deleteNode = self.search(element) if deleteNode is not None: return self.deleteNode(deleteNode) else: return None def deleteNode(self, delNode): if delNode is not None: nodeToReturn = None if delNode is not None: if delNode.left is None: nodeToReturn = self.transplant(delNode, delNode.right) elif delNode.right is None: nodeToReturn = self.transplant(delNode, delNode.left) else: successorNode = self.getMinimum(delNode.right) if successorNode.parent != delNode: self.transplant(successorNode, successorNode.right) successorNode.right = delNode.right successorNode.right.parent = successorNode self.transplant(delNode, successorNode) successorNode.left = delNode.left successorNode.left.parent = successorNode nodeToReturn = successorNode self.size -= 1 return nodeToReturn def transplant(self, nodeToReplace, newNode): if nodeToReplace.parent is None: self.root = newNode elif nodeToReplace == nodeToReplace.parent.left: nodeToReplace.parent.left = newNode else: nodeToReplace.parent.right = newNode if newNode is not None: newNode.parent = nodeToReplace.parent return newNode def getMinimum(self, node): while node.left is not None: node = node.left return node class AVLNode(object): def __init__(self, value, parent, left, right, height): self.value = value self.parent = parent self.left = left self.right = right self.height = height class AVLTree(AbstractBinarySearchTree): def insert(self, element): newNode = self.insert(element) return newNode def rebalance(self, pHead): while pHead is not None: parentNode = pHead.parent leftHeight = -1 if pHead.left is None else pHead.left.height rightHeight = -1 if pHead.right is None else pHead.right.height nodeBalance = rightHeight - leftHeight if nodeBalance == 2: if pHead.right.right is not None: pHead = self.avlRotateLeft(pHead) break else: pHead = self.doubleRotateRightLeft(pHead) break elif nodeBalance == -2: if pHead.left.left is not None: pHead = self.avlRotateRight(pHead) break else: pHead = self.doubleRotateLeftRight(pHead) break else: self.updateHeight(pHead) pHead = parentNode def updateHeight(self, pHead): leftHeight = -1 if pHead.left is None else pHead.left.height rightHeight = -1 if pHead.right is None else pHead.right.height pHead.height = 1 + max(leftHeight, rightHeight) def avlRotateLeft(self, pHead): temp = self.rotateLeft(pHead) self.updateHeight(temp.left) self.updateHeight(temp) return temp def avlRotateRight(self, pHead): temp = self.rotateRight(pHead) self.updateHeight(temp.right) self.updateHeight(temp) return temp def doubleRotateRightLeft(self, pHead): pHead.right = self.avlRotateRight(pHead.right) return self.avlRotateLeft(pHead) def doubleRotateLeftRight(self, pHead): pHead.left = self.avlRotateLeft(pHead.left) return self.avlRotateRight(pHead) def rotateLeft(self, pHead): temp = pHead.right temp.parent = pHead.parent pHead.right = temp.left if pHead.right is not None: pHead.right.parent = pHead temp.left = pHead pHead.parent = temp # temp took over node's place so now its parent should point to temp if temp.parent is not None: if pHead == temp.parent.left: temp.parent.left = temp else: temp.parent.right = temp else: self.root = temp return temp def rotateRight(self, pHead): temp = pHead.left temp.parent = pHead.parent pHead.left = temp.right if pHead.left is not None: pHead.left.parent = pHead temp.right = pHead pHead.parent = temp # temp took over node's place so now its parent should point to temp if temp.parent is not None: if pHead == temp.parent.left: temp.parent.left = temp else: temp.parent.right = temp else: self.root = temp return temp def maxLength(alist, aim): """给定数组,返回满足累加和为aim的子数组的最大长度""" if alist == [] or len(alist) == 0: return 0 mapDict = {} mapDict.update({0: -1}) maxLen, sumNum = 0, 0 for i in range(len(alist)): sumNum += alist[i] if (sumNum - aim) in mapDict.keys(): maxLen = max(i - mapDict.get(sumNum - aim), maxLen) if sumNum not in mapDict.keys(): mapDict.update({sumNum: i}) return maxLen def mostEOR(alist): """将给定数组进行分组,保证每组的异或和为0,返回最多的子数组数""" ans, xor = 0, 0 dp = [0] * len(alist) mapDict = {} mapDict.update({0: -1}) for i in range(len(alist)): xor ^= alist[i] if xor in mapDict.keys(): pre = mapDict.get(xor) dp[i] = 1 if pre == -1 else dp[pre] + 1 if i > 0: dp[i] = max(dp[i - 1], dp[i]) mapDict.update({xor: i}) ans = max(ans, dp[i]) return ans def biggestSubNSTInTree(pHead): record = [] * 3 # 0 -> size 1 -> min 2 -> max return posOrder(pHead, record) def posOrder(pHead, record): if pHead is None: record[0] = 0 record[1] = 0 record[2] = 0 return None value = pHead.value leftNode = pHead.left rightNode = pHead.right lBST = posOrder(leftNode, record) lSize = record[0] lMin = record[1] lMax = record[2] rBST = posOrder(rightNode, record) rSize = record[0] rMin = record[1] rMax = record[2] record[1] = min(rMin, lMin, value) # lmin, value, rmin -> min record[2] = max(lMax, rMax, value) # lmax, value, rmax -> max if leftNode == lBST and rightNode == rBST and lMax < value < rMin: record[0] = lSize + rSize + 1 return pHead record[0] = max(lSize, rSize) return lBST if lSize > rSize else rBST def biggestSubNSTInTreeProcess(pHead): if pHead is None: return 0, None, 0, 0 leftTree = pHead.left leftSubTressInfo = biggestSubNSTInTreeProcess(leftTree) rightTree = pHead.right rightSubTressInfo = biggestSubNSTInTreeProcess(rightTree) includeItSelf = 0 if leftSubTressInfo[1] == leftTree and rightSubTressInfo[1] == rightTree and \ rightSubTressInfo[2] > pHead.value > leftSubTressInfo[2]: includeItSelf = leftSubTressInfo[0] + 1 + rightSubTressInfo[0] p1, p2 = leftSubTressInfo[0], rightSubTressInfo[0] maxSize = max(p1, p2, includeItSelf) maxpHead = leftSubTressInfo[1] if p1 > p2 else rightSubTressInfo[1] if maxSize == includeItSelf: maxpHead = pHead return maxSize, maxpHead # 节点A走到节点B的距离为:A走到B最短路径上的节点个数。求一颗二叉树上的最远距离 def MaxDistanceInTree(pHead): """节点A走到节点B的距离为:A走到B最短路径上的节点个数。求一颗二叉树上的最远距离""" return MaxDistanceInTreeProcess(pHead)[0] def MaxDistanceInTreeProcess(pHead): if pHead is None: return 0, 0 leftReturnType = MaxDistanceInTreeProcess(pHead.left) rightReturnType = MaxDistanceInTreeProcess(pHead.right) includeHeadDistance = leftReturnType[1] + 1 + rightReturnType[1] p1, p2 = leftReturnType[0], rightReturnType[0] resultDistance = max(p1, p2, includeHeadDistance) hitself = max(leftReturnType[1], rightReturnType[1]) + 1 return resultDistance, hitself class maxHappyNode(object): def __init__(self, huo): self.huo = huo self.nexts = [] def getMaxHuo(pHead): """活跃度的计算""" return max(getMaxHuoProcess(pHead)[0], getMaxHuoProcess(pHead)[1]) def getMaxHuoProcess(pHead): lai_huo, bu_lai_huo = pHead.huo, 0 if pHead.nexts == []: return pHead.huo, 0 for i in range(len(pHead.nexts)): nextNode = pHead.nexts[i] nextNodeReturn = getMaxHuoProcess(nextNode) lai_huo += nextNodeReturn[1] bu_lai_huo = max(nextNodeReturn[0], nextNodeReturn[1]) return lai_huo, bu_lai_huo class LRUNode(object): def __init__(self, value): self.value = value self.last = None self.next = None class NodeDoubleLinkedList(object): def __init__(self): self.head = None self.tail = None def addNode(self, newNode): if newNode is None: return None if self.head is None: self.head = newNode self.tail = newNode else: self.tail.next = newNode newNode.last = self.tail self.tail = newNode def moveNodeToTail(self, pHead): if self.tail == pHead: return if self.head == pHead: self.head = pHead.next self.head.last = None else: pHead.last.next = pHead.next pHead.next.last = pHead.last pHead.last = self.tail pHead.next = None self.tail.next = pHead self.tail = pHead def removeHead(self): if self.head is None: return None res = self.head if self.head == self.tail: self.head = None self.tail = None else: self.head = res.next res.next = None self.head.last = None return res # 自定义一种缓存结构(LRU),假设大小为K,能实现两个功能set()和get() # set和get方法的时间复杂度为O(1) # 某个key的set或get操作一旦发生,则认为这个key的记录成了最经常使用的 # 当缓存的大小超过K时,移除最不经常使用的记录 class MyCache(object): def __init__(self, capacity): if capacity < 1: # capacity指限定的内存大小 raise RuntimeError("should be more than 0.") self.keyNodeMap = {} self.nodeKeyMap = {} self.nodeList = NodeDoubleLinkedList() self.capacity = capacity def get(self, K): if K in self.keyNodeMap.keys(): res = self.keyNodeMap[K] self.nodeList.moveNodeToTail(res) return res.value return None def set(self, K, V): if K in self.keyNodeMap.keys(): node = self.keyNodeMap[K] node.value = V self.nodeList.moveNodeToTail(node) else: newNode = LRUNode(V) self.keyNodeMap.update({K: newNode}) self.nodeKeyMap.update({newNode: K}) self.nodeList.addNode(newNode) if len(self.keyNodeMap) == self.capacity + 1: self.removeMostUnusedCache() def removeMostUnusedCache(self): removeNode = self.nodeList.removeHead() K = self.nodeKeyMap[removeNode] del self.nodeKeyMap[removeNode] del self.keyNodeMap[K] class LFUNode(object): def __init__(self, key, value, times): self.key = key self.value = value self.times = times self.up = None self.down = None class NodeList(object): def __init__(self, pHead): self.next = None self.last = None self.head = pHead self.tail = pHead def addNodeFromHead(self, newHead): newHead.down = self.head self.head = newHead def isEmpty(self): return self.head is None def deleteNode(self, pHead): """删除任意节点pHead""" if self.head == self.tail: self.head = None self.tail = None elif pHead == self.head: self.head = pHead.down self.head.up = None elif pHead == self.tail: self.tail = pHead.up self.tail.down = None else: pHead.up.down = pHead.down pHead.down.up = pHead.up pHead.up = None pHead.down = None class LFUCache(object): def __init__(self, capacity): self.capacity = capacity # 容量 self.size = 0 # 实际存储的个数 self.records = {} # key(Integer): node self.heads = {} # node: NodeList self.headlist = NodeList(None) def set(self, key, value): if key in self.records.keys(): pHead = self.records[key] pHead.value = value pHead.times += 1 curNodeList = self.heads[pHead] self.move(pHead, curNodeList) else: if self.size == self.capacity: pHead = self.headlist.tail self.headlist.deleteNode(pHead) self.modifyHeadList(self.headlist) del self.records[pHead.key] del self.heads[pHead] self.size -= 1 pHead = LFUNode(key, value, 1) if self.headlist is None: self.headlist = NodeList(pHead) elif self.headlist.head.times == pHead.times: self.headlist.addNodeFromHead(pHead) else: newList = NodeList(pHead) newList.next = self.headlist self.headlist.last = newList self.headlist = newList self.records.update({key: pHead}) self.heads.update({pHead: self.headlist}) self.size += 1 def get(self, key): if key not in self.records.keys(): return -1 pHead = self.records[key] pHead.times += 1 curNodeList = self.heads[pHead] self.move(pHead, curNodeList) return pHead.value # return whether delete this head def modifyHeadList(self, nodeList): if nodeList.isEmpty(): if self.headlist == nodeList: self.headlist = nodeList.next if self.headlist is not None: self.headlist.last = None else: nodeList.last.next = nodeList.next if nodeList.next is not None: nodeList.next.last = nodeList.last return True return False # 将一个节点从老链表拿出,送到新链表中,需要考虑: # 老链表在删除之后,是否还有存在必要(老链表中只有一个节点) # 老链表是否是头链表 # 新链表是否存在(老链表是否是尾链表) # 新链表是否与老链表在次数是相连的(比如老链表中的times均是4,而与之相连的链表的times为6,此时需要新建一个times为5的链表) def move(self, node, oldNodeList): oldNodeList.deleteNode(node) preList = oldNodeList.last if self.modifyHeadList(oldNodeList) else oldNodeList nextList = oldNodeList.next if nextList is None: newList = NodeList(node) if preList is not None: preList.next = newList newList.last = preList if self.headlist is None: self.headlist = newList self.heads.update({node, newList}) else: if nextList.head.times == node.times: nextList.addNodeFromHead(node) self.heads.update({node, nextList}) else: newList = NodeList(node) if preList is not None: preList.next = newList newList.last = preList newList.next = nextList nextList.last = newList if self.headlist == nextList: self.headlist = newList self.heads.update({node, newList})
数据结构与算法--python学习笔记四(听了左神的课,自己整理的,左神还是强啊)
最新推荐文章于 2023-04-21 14:56:45 发布