classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classUnsortedPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with an unsorted list."""def__init__(self):"""Create a new empty Priority Queue."""
self._data = PositionalList()defadd(self, key, value):"""Add a key-value pair."""
newest = self._Item(key, value)# make new item instance
walk = self._data.last()# walk backward looking for smaller keywhile walk isnotNoneand newest < walk.element():
walk = self._data.before(walk)if walk isNone:
self._data.add_first(newest)# new key is smallestelse:
self._data.add_after(walk, newest)# new goes after walkdefmin(self):"""Return but do not remove(k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
p = self._data.first()
item = p.element()return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data.delete(self._data.first())return item._key, item._value
def__len__(self):"""Return the number of items in the priotity queue."""returnlen(self._data)if __name__ =='__main__':
priorityQueue = UnsortedPriorityQueue()
priorityQueue.add(1,2)
priorityQueue.add(2,3)
priorityQueue.add(3,4)print(priorityQueue.min())
9.6
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classUnsortedPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with an unsorted list."""def__init__(self):"""Create a new empty Priority Queue."""
self._data = PositionalList()defadd(self, key, value):"""Add a key-value pair."""
newest = self._Item(key, value)# make new item instance
walk = self._data.last()# walk backward looking for smaller keywhile walk isnotNoneand newest < walk.element():
walk = self._data.before(walk)if walk isNone:
self._data.add_first(newest)# new key is smallestelse:
self._data.add_after(walk, newest)# new goes after walkdefmin(self):"""Return but do not remove(k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
p = self._data.first()
item = p.element()return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data.delete(self._data.first())return item._key, item._value
def__len__(self):"""Return the number of items in the priotity queue."""returnlen(self._data)if __name__ =='__main__':
priorityQueue = UnsortedPriorityQueue()
priorityQueue.add(1,2)
priorityQueue.add(2,3)
priorityQueue.add(3,4)
priorityQueue.add(4,5)
priorityQueue.add(5,6)print(priorityQueue.min())
9.12
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with a binary heap."""# --------------------nonpublic behaviors ----------------------------def_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)<len(self._data)# index beyond end of list?def_has_right(self, j):return self._right(j)<len(self._data)# index beyond end of list?def_swap(self, i, j):"""Swap the elements at indices i and j of array."""
self._data[i], self._data[j]= self._data[j], self._data[i]def_upheap(self, j):
parent = self._parent(j)if j >0and self._data[j]> self._data[parent]:
self._swap(j, parent)
self._upheap(parent)# recur at position of parentdef_downheap(self, j):if self._has_left(j):
left = self._left(j)
small_child = left # although right may by smallerif self._has_right(j):
right = self._right(j)if self._data[right]> self._data[left]:
small_child = right
if self._data[small_child]> self._data[j]:
self._swap(j, small_child)
self._downheap(small_child)# recur at position of small childdef__init__(self):"""Create a new empty Priority Queue."""
self._data =[]def__len__(self):"""Return the number of items in the priority queue."""returnlen(self._data)defadd(self, key, value):"""Add a key-value pair to the priority queue."""
self._data.append(self._Item(key, value))
self._upheap(len(self._data)-1)# upheap newly added positiondefmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_max(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)return item._key, item._value
def__str__(self):
temp =[]for data in self._data:
temp.append(data._key)returnstr(temp)if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(1,10)
priorityQueue.add(3,5)
priorityQueue.add(4,12)
priorityQueue.add(2,7)
priorityQueue.add(5,4)
priorityQueue.add(7,1)
priorityQueue.add(6,2)
priorityQueue.add(9,3)
priorityQueue.add(8,8)print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)print(priorityQueue.remove_max())print(priorityQueue)
9.26
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdef__cmp__(self, other):return self._key == other.key
defis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classSortedPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with a sorted list."""def__init__(self):"""Create a new empty Priority Queue."""
self._data = PositionalList()def__len__(self):"""Return the number of items in the priotity queue."""returnlen(self._data)defadd(self, key, value):"""Add a key-value pair."""
newest = self._Item(key, value)# make new item instance
walk = self._data.last()# walk backward looking for smaller keywhile walk isnotNoneand newest < walk.element():
walk = self._data.before(walk)if walk isNone:
self._data.add_first(newest)# new key is smallestelse:
self._data.add_after(walk, newest)# new goes after walkdefmin(self):"""Return but do not remove(k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
p = self._data.first()
item = p.element()return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data.delete(self._data.first())return item._key, item._value
defreplace(self, key, value):
walk = self._data.first()while walk isnotNone:if walk == key:
walk._value = value
break
walk = self._data.after(walk)else:returnNoneclassAdaptHeapPriorityQueue:def__init__(self):
self._data = SortedPriorityQueue()
self._index =0def__len__(self):return self._index
defpush(self, key, value):# 默认从小到大排列,如果需要从大到小,那么key取负数
self._data.add(key, value)
self._index +=1defpop(self):if self._index ==0:raise IndexError
self._index -=1return self._data.remove_min()defreplace(self, key, value):
self._data._replace(key, value)if __name__ =="__main__":
Heap = AdaptHeapPriorityQueue()
Heap.push(4,1)
Heap.push(1,0)
Heap.push(2,1)
Heap.push(3,2)print(Heap.pop())print(Heap.pop())print(Heap.pop())
9.27
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdef__cmp__(self, other):return self._key == other.key
defis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classSortedPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with a sorted list."""def__init__(self):"""Create a new empty Priority Queue."""
self._data = PositionalList()def__len__(self):"""Return the number of items in the priotity queue."""returnlen(self._data)defadd(self, key, value):"""Add a key-value pair."""
newest = self._Item(key, value)# make new item instance
walk = self._data.last()# walk backward looking for smaller keywhile walk isnotNoneand newest < walk.element():
walk = self._data.before(walk)if walk isNone:
self._data.add_first(newest)# new key is smallestelse:
self._data.add_after(walk, newest)# new goes after walkdefmin(self):"""Return but do not remove(k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
p = self._data.first()
item = p.element()return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key."""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data.delete(self._data.first())return item._key, item._value
defreplace(self, key, value):
walk = self._data.first()while walk isnotNone:if walk == key:
walk._value = value
break
walk = self._data.after(walk)else:returnNoneclassFIFOQueue:def__init__(self):
self._data = SortedPriorityQueue()
self._index =0def__len__(self):return self._index
defpush(self, value):# 默认从小到大排列,如果需要从大到小,那么key取负数
self._data.add(self._index, value)
self._index +=1defpop(self):if self._index ==0:raise IndexError
self._index -=1return self._data.remove_min()defreplace(self, key, value):
self._data._replace(key,value)if __name__ =="__main__":
Fifoqueue = FIFOQueue()
Fifoqueue.push(1)
Fifoqueue.push(0)
Fifoqueue.push(1)
Fifoqueue.push(2)print(Fifoqueue.pop())print(Fifoqueue.pop())print(Fifoqueue.pop())
9.29
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key','_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key # compare items based on their keysdef__cmp__(self, other):return self._key == other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classSortedPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority implemented with a sorted list."""def__init__(self):
self._data =[]def__len__(self):returnlen(self._data)defis_empty(self):returnlen(self._data)==0defadd(self, key, value):
Item = self._Item(key, value)if self.is_empty():
self._data.append(Item)else:
walk =0while walk <len(self._data):if self._data[walk]< Item:break
walk +=1
self._data = self._data[:walk]+[Item]+ self._data[walk:]defmin(self):return self._data[-1]._key, self._data[-1]._value
defremove_min(self):iflen(self._data)==0:raise Empty
temp = self._data.pop()return temp._key, temp._value
if __name__ =="__main__":
priorityQueue = SortedPriorityQueue()
priorityQueue.add(6,1)
priorityQueue.add(2,2)
priorityQueue.add(1,2)
priorityQueue.add(3,2)
priorityQueue.add(9,2)print(priorityQueue.min())
9.30
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with a binary heap."""# --------------------nonpublic behaviors ----------------------------def_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)<len(self._data)# index beyond end of list?def_has_right(self, j):return self._right(j)<len(self._data)# index beyond end of list?def_swap(self, i, j):"""Swap the elements at indices i and j of array."""
self._data[i], self._data[j]= self._data[j], self._data[i]def_upheap(self, j):
now = j
parent = self._parent(j)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):if self._has_left(j):
left = self._left(j)
small_child = left # although right may by smallerif self._has_right(j):
right = self._right(j)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[j]:
self._swap(j, small_child)
self._downheap(small_child)# recur at position of small childdef__init__(self):"""Create a new empty Priority Queue."""
self._data =[]def__len__(self):"""Return the number of items in the priority queue."""returnlen(self._data)defadd(self, key, value):"""Add a key-value pair to the priority queue."""
self._data.append(self._Item(key, value))
self._upheap(len(self._data)-1)# upheap newly added positiondefmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)return item._key, item._value
if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,3)
priorityQueue.add(1,2)
priorityQueue.add(4,3)
priorityQueue.add(3,3)
priorityQueue.add(5,4)print(priorityQueue.min())
9.31
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with a binary heap."""# --------------------nonpublic behaviors ----------------------------def_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)<len(self._data)# index beyond end of list?def_has_right(self, j):return self._right(j)<len(self._data)# index beyond end of list?def_swap(self, i, j):"""Swap the elements at indices i and j of array."""
self._data[i], self._data[j]= self._data[j], self._data[i]def_upheap(self, j):
now = j
parent = self._parent(j)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
whileTrue:if self._has_left(now):
left = self._left(now)
small_child = left # although right may by smallerif self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)continuebreakdef__init__(self):"""Create a new empty Priority Queue."""
self._data =[]def__len__(self):"""Return the number of items in the priority queue."""returnlen(self._data)defadd(self, key, value):"""Add a key-value pair to the priority queue."""
self._data.append(self._Item(key, value))
self._upheap(len(self._data)-1)# upheap newly added positiondefmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)return item._key, item._value
if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,3)
priorityQueue.add(1,2)
priorityQueue.add(4,3)
priorityQueue.add(3,3)
priorityQueue.add(5,4)print(priorityQueue.remove_min())
9.32
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
whileTrue:if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)continuebreakdef__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
deflast(self):return self._trailer._key, self._trailer._value
if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,3)print(priorityQueue.last())
priorityQueue.add(1,2)print(priorityQueue.last())
priorityQueue.add(4,3)print(priorityQueue.last())
priorityQueue.add(3,3)print(priorityQueue.last())
priorityQueue.add(5,4)print(priorityQueue.last())
9.33
from collections import deque
classEmpty(Exception):passclassTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_set_root(self, node):
node = self._validate(node)
self._root = node
return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0def_swap(self, p, q):
node_p = self._validate(p)
node_q = self._validate(q)
node_p_parent = node_p._parent
node_q_parent = node_q._parent
node_p_left = node_p._left
node_p_right = node_p._right
node_q_left = node_q._left
node_q_right = node_q._right
node_p._parent = node_q_parent if node_q_parent != node_p else node_q
node_q._parent = node_p_parent if node_p_parent != node_q else node_p
node_p._left = node_q_left if node_q_left != node_p else node_q
try:if node_p_left != node_q:
node_p_left._parent = node_q
except Exception:pass
node_p._right = node_q_right if node_q_right != node_p else node_q
try:if node_p_right != node_q:
node_p_right._parent = node_q
except Exception:pass
node_q._left = node_p_left if node_p_left != node_q else node_p
try:if node_q_left != node_p:
node_q_left._parent = node_p
except Exception:pass
node_q._right = node_p_right if node_p_right != node_q else node_p
try:if node_q_right != node_p:
node_q_right._parent = node_p
except Exception:passtry:if node_p_parent isNoneor node_q_parent isNone:if node_p_parent isNone:if node_q_parent isNone:passelse:
self._root = node_q
if node_p_left == node_q:
node_q._left = node_p
elif node_p_right == node_q:
node_q._right = node_p
else:passelse:
self._root = node_p
if node_q_left == node_p:
node_p._left = node_q
elif node_q_right == node_p:
node_p._right = node_q
else:passtry:if node_p_parent._left is node_p and node_p_parent isnot node_q:
node_p_parent._left = node_q
elif node_p_parent._right is node_p and node_p_parent isnot node_q:
node_p_parent._right = node_q
else:passexcept Exception:passtry:if node_q_parent._left is node_q and node_q_parent isnot node_p:
node_q_parent._left = node_p
elif node_q_parent._right is node_q:
node_q_parent._right = node_p
else:passexcept Exception:passexcept Exception:passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data = LinkedBinaryTree()
self._trailer =Nonedef__iter__(self):
data = deque()
root = self._data.root()
data.append(root)whilelen(data)!=0:
node = data.popleft()yield node
for child in self._data.children(node):
data.append(child)def_parent(self, p):return self._data.parent(p)def_left(self, p):return self._data.left(p)def_right(self, p):return self._data.right(p)def_has_left(self, p):return self._left(p)isnotNonedef_has_right(self, p):return self._right(p)isnotNonedef_uphead(self, p):
now = p
parent = self._parent(now)while parent isnotNoneand now isnotNone:if now.element()< parent.element():if now.element()is self._trailer.element():
self._trailer = parent
self._data._swap(now, parent)
parent = self._parent(now)else:
now = parent
parent = self._parent(now)def_downheap(self, p):
now = p
whileTrue:if self._data.left(now)isnotNone:
left = self._data.left(now)
small_child = left
if self._data.right(now)isnotNone:
right = self._data.right(now)if right.element()< left.element():
small_child = right
if small_child.element()< now.element():if now.element()is self._trailer.element():
self._trailer = now
self._data._swap(now, small_child)continuebreakdef__len__(self):"""Return the number of items in the priority queue."""returnlen(self._data)def_push_node_position(self):"""确定插入的父节点"""
root = self._data.root()if root isNone:raise Empty("root is None")
data = deque()
data.append(root)whileTrue:# 使用队列来找父节点
node = data.popleft()if self._data.num_children(node)!=2:return node
for child in self._data.children(node):
data.append(child)def_update_trailer(self):"""更新尾结点用来做删除操作"""
root = self._data.root()if root isNone:raise Empty("root is None")
data = deque()
temp =[root]
data.append(root)whilelen(data)!=0:# 使用队列来找父节点
node = data.popleft()for child in self._data.children(node):
data.append(child)
temp.append(child)iflen(data)==1:
self._trailer = root
else:
self._trailer = temp[-1]passdefadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)if self._data.root()isNone:
self._data._add_root(items)
self._trailer = self._data.root()else:
get_node = self._push_node_position()# 申明这里的时间复杂度不是(1)是(n)if self._data.left(get_node)isNone:
self._data._add_left(get_node, items)
self._trailer = self._data.left(get_node)else:
self._data._add_right(get_node, items)
self._trailer = self._data.right(get_node)
self._uphead(self._trailer)defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")return self._trailer.element()._key, self._trailer.element()._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
root = self._data.root()
self._data._swap(root, self._trailer)# 交换到最后一个位置
self._data._delete(root)# 从尾巴删掉
self._update_trailer()# 更新尾结点
self._downheap(self._data.root())# 向下更新return root.element()._key, root.element()._value
if __name__ =='__main__':
heapPriorityQueue = HeapPriorityQueue()
heapPriorityQueue.add(7,7)
heapPriorityQueue.add(2,8)
heapPriorityQueue.add(3,7)
heapPriorityQueue.add(1,9)
heapPriorityQueue.add(5,7)
heapPriorityQueue.add(6,7)print(heapPriorityQueue.remove_min())for node in heapPriorityQueue:print(node.element()._key, node.element()._value)pass
9.34
from collections import deque
classEmpty(Exception):passclassTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_set_root(self, node):
node = self._validate(node)
self._root = node
return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0def_swap(self, p, q):
node_p = self._validate(p)
node_q = self._validate(q)
node_p_parent = node_p._parent
node_q_parent = node_q._parent
node_p_left = node_p._left
node_p_right = node_p._right
node_q_left = node_q._left
node_q_right = node_q._right
node_p._parent = node_q_parent if node_q_parent != node_p else node_q
node_q._parent = node_p_parent if node_p_parent != node_q else node_p
node_p._left = node_q_left if node_q_left != node_p else node_q
try:if node_p_left != node_q:
node_p_left._parent = node_q
except Exception:pass
node_p._right = node_q_right if node_q_right != node_p else node_q
try:if node_p_right != node_q:
node_p_right._parent = node_q
except Exception:pass
node_q._left = node_p_left if node_p_left != node_q else node_p
try:if node_q_left != node_p:
node_q_left._parent = node_p
except Exception:pass
node_q._right = node_p_right if node_p_right != node_q else node_p
try:if node_q_right != node_p:
node_q_right._parent = node_p
except Exception:passtry:if node_p_parent isNoneor node_q_parent isNone:if node_p_parent isNone:if node_q_parent isNone:passelse:
self._root = node_q
if node_p_left == node_q:
node_q._left = node_p
elif node_p_right == node_q:
node_q._right = node_p
else:passelse:
self._root = node_p
if node_q_left == node_p:
node_p._left = node_q
elif node_q_right == node_p:
node_p._right = node_q
else:passtry:if node_p_parent._left is node_p and node_p_parent isnot node_q:
node_p_parent._left = node_q
elif node_p_parent._right is node_p and node_p_parent isnot node_q:
node_p_parent._right = node_q
else:passexcept Exception:passtry:if node_q_parent._left is node_q and node_q_parent isnot node_p:
node_q_parent._left = node_p
elif node_q_parent._right is node_q:
node_q_parent._right = node_p
else:passexcept Exception:passexcept Exception:passdeflast(self):
root = self.root()
depth =0while root isnotNone:
root = self.left(root)
depth +=1
root = self.root()
level =0
path =""# path 用来记录路线while root isnotNone:
now_node = root
level +=1# 判断是否有右孩子if level == depth:breakif self.right(now_node)isnotNone:
current_node = self.right(now_node)
tempdepth = level +1# 临时深度,用来判断是否与最大深度一致
parent = current_node # 用来记录最左边节点的父节点
temppath =""while self.left(current_node)isnotNone:
tempdepth +=1
parent = current_node
current_node = self.left(current_node)
temppath = temppath[:]+"0"if tempdepth < depth:# 只要当前深度小于最大深度,# 说明该位置不对,应该在当前节点的起点往左走而不是由走
root = self.left(root)
path = path[:]+"0"elif self.right(parent)isNoneand tempdepth == depth:# 如果循环到最大位置处是,该深度与树的最大深度一致则返回if temppath isnotNone:return path[:]+"1"+ temppath[:]else:return path[:]+"1"else:# 上诉所有不满足者即有可能有右孩子,从root右孩子继续遍历
root = self.right(root)
path = path[:]+"1"else:# 没有就进入左孩子
root = self.left(root)
path = path[:]+"0"return path
if __name__ =="__main__":
tree = LinkedBinaryTree()
tree._add_root(1)
tree._add_left(tree.root(),2)
tree._add_right(tree.root(),3)
tree._add_left(tree.left(tree.root()),4)
tree._add_right(tree.left(tree.root()),5)
tree._add_left(tree.right(tree.root()),6)
tree._add_right(tree.right(tree.root()),7)
tree._add_left(tree.left(tree.left(tree.root())),8)
tree._add_right(tree.left(tree.left(tree.root())),9)
tree._add_left(tree.right(tree.left(tree.root())),10)
tree._add_right(tree.right(tree.left(tree.root())),11)
tree._add_left(tree.left(tree.right(tree.root())),12)
tree._add_right(tree.left(tree.right(tree.root())),13)print(tree.last())
9.35
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,'B')
priorityQueue.add(4,"C")
priorityQueue.add(5,"A")
priorityQueue.add(9,"F")
priorityQueue.add(15,"K")
priorityQueue.add(6,"Z")
priorityQueue.add(7,"Q")
priorityQueue.add(25,"J")
priorityQueue.add(16,"X")
priorityQueue.add(12,"H")
priorityQueue.add(14,"E")
priorityQueue.add(8,"W")
priorityQueue.add(20,"B")
priorityQueue.add(11,"S")
priorityQueue.add(10,"L")print(priorityQueue.find_all_min(7))
9.38
from collections import deque
classEmpty(Exception):passclassTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""# if not isinstance(p, self.Position):# raise TypeError("p must be proper Position type")# if p._container is not self:# raise ValueError("p does not belong to this container")# if p._node._parent is p._node: # convention for deprecated nodes# raise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_set_root(self, node):
node = self._validate(node)
self._root = node
return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0return node
def_swap(self, p, q):
node_p = self._validate(p)
node_q = self._validate(q)
node_p_parent = node_p._parent
node_q_parent = node_q._parent
node_p_left = node_p._left
node_p_right = node_p._right
node_q_left = node_q._left
node_q_right = node_q._right
node_p._parent = node_q_parent if node_q_parent != node_p else node_q
node_q._parent = node_p_parent if node_p_parent != node_q else node_p
node_p._left = node_q_left if node_q_left != node_p else node_q
try:if node_p_left isnot node_q:
node_p_left._parent = node_q
except Exception:pass
node_p._right = node_q_right if node_q_right != node_p else node_q
try:if node_p_right isnot node_q:
node_p_right._parent = node_q
except Exception:pass
node_q._left = node_p_left if node_p_left != node_q else node_p
try:if node_q_left isnot node_p:
node_q_left._parent = node_p
except Exception:pass
node_q._right = node_p_right if node_p_right != node_q else node_p
try:if node_q_right isnot node_p:
node_q_right._parent = node_p
except Exception:passtry:if node_p_parent isNoneor node_q_parent isNone:if node_p_parent isNone:if node_q_parent isNone:passelse:
self._root = node_q
if node_p_left == node_q:
node_q._left = node_p
elif node_p_right == node_q:
node_q._right = node_p
else:passelse:
self._root = node_p
if node_q_left == node_p:
node_p._left = node_q
elif node_q_right == node_p:
node_p._right = node_q
else:passtry:if node_p_parent._left is node_p and node_p_parent isnot node_q:
node_p_parent._left = node_q
elif node_p_parent._right is node_p and node_p_parent isnot node_q:
node_p_parent._right = node_q
else:passexcept Exception:passtry:if node_q_parent._left is node_q and node_q_parent isnot node_p:
node_q_parent._left = node_p
elif node_q_parent._right is node_q:
node_q_parent._right = node_p
else:passexcept Exception:passexcept Exception:passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data = LinkedBinaryTree()
self._trailer =Nonedef__iter__(self):
data = deque()
root = self._data.root()
data.append(root)whilelen(data)!=0:
node = data.popleft()yield node
for child in self._data.children(node):
data.append(child)def_parent(self, p):return self._data.parent(p)def_left(self, p):return self._data.left(p)def_right(self, p):return self._data.right(p)def_has_left(self, p):return self._left(p)isnotNonedef_has_right(self, p):return self._right(p)isnotNonedef_uphead(self, p):
now = p
parent = self._parent(now)while parent isnotNoneand now isnotNone:if now.element()< parent.element():if now.element()is self._trailer.element():
self._trailer = parent
self._data._swap(now, parent)
parent = self._parent(now)else:
now = parent
parent = self._parent(now)def_downheap(self, p):
now = p
whileTrue:if self._data.left(now)isnotNone:
left = self._data.left(now)
small_child = left
if self._data.right(now)isnotNone:
right = self._data.right(now)if right.element()< left.element():
small_child = right
if small_child.element()< now.element():if now.element()is self._trailer.element():
self._trailer = now
self._data._swap(now, small_child)continuebreakdef__len__(self):"""Return the number of items in the priority queue."""returnlen(self._data)def_push_node_position(self):"""确定插入的父节点"""
root = self._data.root()if root isNone:raise Empty("root is None")
data = deque()
data.append(root)whileTrue:# 使用队列来找父节点
node = data.popleft()if self._data.num_children(node)!=2:return node
for child in self._data.children(node):
data.append(child)def_update_trailer(self):"""更新尾结点用来做删除操作"""
root = self._data.root()if root isNone:raise Empty("root is None")
data = deque()
temp =[root]
data.append(root)whilelen(data)!=0:# 使用队列来找父节点
node = data.popleft()for child in self._data.children(node):
data.append(child)
temp.append(child)iflen(data)==1:
self._trailer = root
else:
self._trailer = temp[-1]passdefadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)if self._data.root()isNone:
self._data._add_root(items)
self._trailer = self._data.root()else:
get_node = self._push_node_position()# 申明这里的时间复杂度不是(1)是(n)if self._data.left(get_node)isNone:
self._data._add_left(get_node, items)
self._trailer = self._data.left(get_node)else:
self._data._add_right(get_node, items)
self._trailer = self._data.right(get_node)
self._uphead(self._trailer)defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")return self._trailer.element()._key, self._trailer.element()._value
defremove_min(self, position=False):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
root = self._data.root()
self._data._swap(root, self._trailer)# 交换到最后一个位置
self._data._delete(root)# 从尾巴删掉
self._update_trailer()# 更新尾结点
self._downheap(self._data.root())# 向下更新if position:return root
else:return root.element()._key, root.element()._value
defattch(self, heap):
root = self._data.root()
self._data._swap(root, self._trailer)# 交换到最后一个位置if root._node is root._node._parent._left:
root._node._parent._left =Noneelse:
root._node._parent._right =None
self._update_trailer()# 更新尾结点
self._downheap(self._data.root())# 向下更新
root._node._left = self._data._root
root._node._right = heap._data._root
self._data._root = root._node
self._update_trailer()# 更新尾结点
self._downheap(self._data.root())# 向下更新if __name__ =='__main__':
heapPriorityQueue1 = HeapPriorityQueue()
heapPriorityQueue2 = HeapPriorityQueue()
heapPriorityQueue1.add(7,7)
heapPriorityQueue1.add(2,8)
heapPriorityQueue1.add(3,7)
heapPriorityQueue1.add(1,9)
heapPriorityQueue1.add(5,7)
heapPriorityQueue1.add(6,7)
heapPriorityQueue2.add(1,2)
heapPriorityQueue2.add(5,2)
heapPriorityQueue2.add(2,2)
heapPriorityQueue2.add(3,2)
heapPriorityQueue1.attch(heapPriorityQueue2)for node in heapPriorityQueue1:print(node.element()._key, node.element()._value)pass
9.39
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,'B')
priorityQueue.add(4,"C")
priorityQueue.add(5,"A")
priorityQueue.add(9,"F")
priorityQueue.add(15,"K")
priorityQueue.add(6,"Z")
priorityQueue.add(7,"Q")
priorityQueue.add(25,"J")
priorityQueue.add(16,"X")
priorityQueue.add(12,"H")
priorityQueue.add(14,"E")
priorityQueue.add(8,"W")
priorityQueue.add(20,"B")
priorityQueue.add(11,"S")
priorityQueue.add(10,"L")print(priorityQueue.remove_min())print(priorityQueue.heappushpop(1,'A'))
9.40
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
passif __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,'B')
priorityQueue.add(4,"C")
priorityQueue.add(5,"A")
priorityQueue.add(9,"F")
priorityQueue.add(15,"K")
priorityQueue.add(6,"Z")
priorityQueue.add(7,"Q")
priorityQueue.add(25,"J")
priorityQueue.add(16,"X")
priorityQueue.add(12,"H")
priorityQueue.add(14,"E")
priorityQueue.add(8,"W")
priorityQueue.add(20,"B")
priorityQueue.add(11,"S")
priorityQueue.add(10,"L")print(priorityQueue.heappushpop(1,'A'))print(priorityQueue.heapreplace(11,'22'))
9.41
import math
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self, N):
self._data =[]
self._n =0
self._trailer =None
self._log = math.log(N,2)def_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)if self._n < self._log:
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]else:if key > self.min():
self._data[0]= items
self._downheap(0)defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
passdeftop():passif __name__ =='__main__':
priorityQueue = HeapPriorityQueue(N=16)
priorityQueue.add(2,'B')
priorityQueue.add(4,"C")
priorityQueue.add(5,"A")
priorityQueue.add(11,"F")
priorityQueue.add(917,"F")
priorityQueue.add(23,"F")
priorityQueue.add(76,"F")
priorityQueue.add(34,"F")
priorityQueue.add(29,"F")
priorityQueue.add(87,"F")
priorityQueue.add(65,"F")
priorityQueue.add(12,"F")print(priorityQueue)
9.44
import math
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
passdeftop(self,):
temp =[]for i inrange(int(math.log(self._n))):
temp.append(self.remove_min())return temp
classMaxPriorityQueue(HeapPriorityQueue):"""A locator-based priority queue implemented with a binary heap."""defadd(self, key, value):
self._data.append(self._Item((-1)* key, value))
self._uphead(len(self._data)-1)
self._n +=1defmin(self):if self.is_empty():raise Empty("Priority queue is empty")
item = self._data[0]return item._key *(-1), item._value
defremove_min(self):if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key *(-1), item._value
if __name__ =='__main__':
maxPriorityQueue = MaxPriorityQueue()
maxPriorityQueue.add(2,'B')
maxPriorityQueue.add(4,"C")
maxPriorityQueue.add(5,"A")
maxPriorityQueue.add(9,"F")
maxPriorityQueue.add(15,"K")
maxPriorityQueue.add(6,"Z")
maxPriorityQueue.add(7,"Q")print(maxPriorityQueue.remove_min())
9.45
defcount_bits(k):
numOnes =0
temp = k
while temp !=0:
bit = temp &1if bit ==1:
numOnes +=1
temp = temp >>1return numOnes
defbinaryNumber(number):"""把原来的数字与减一后的值做与运算,只要当前值的最右边为1,
做完与运算后,该位置就会变成0,依次类推"""
count =0while number !=0:
count +=1
number = number & number -1return count
passif __name__ =='__main__':print(count_bits(15))print(binaryNumber(15))
9.46
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue"""class_Item:"""Lightweight composite to store priority."""
__slots__ ='_key',"_value"def__init__(self, k, v):
self._key = k
self._value = v
def__lt__(self, other):return self._key < other._key # compare items based on their keysdefis_empty(self):"""Return True if the priority queue is empty"""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):# base class defines _Item"""A min-oriented priority queue implemented with a binary heap."""# --------------------nonpublic behaviors ----------------------------def_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)<len(self._data)# index beyond end of list?def_has_right(self, j):return self._right(j)<len(self._data)# index beyond end of list?def_swap(self, i, j):"""Swap the elements at indices i and j of array."""
self._data[i], self._data[j]= self._data[j], self._data[i]def_upheap(self, j):
parent = self._parent(j)if j >0and self._data[j]< self._data[parent]:
self._swap(j, parent)
self._upheap(parent)# recur at position of parentdef_downheap(self, j):if self._has_left(j):
left = self._left(j)
small_child = left # although right may by smallerif self._has_right(j):
right = self._right(j)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[j]:
self._swap(j, small_child)
self._downheap(small_child)# recur at position of small childdef__init__(self):"""Create a new empty Priority Queue."""
self._data =[]def__len__(self):"""Return the number of items in the priority queue."""returnlen(self._data)defadd(self, key, value):"""Add a key-value pair to the priority queue."""
self._data.append(self._Item(key, value))
self._upheap(len(self._data)-1)# upheap newly added positiondefmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key, item._value
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._downheap(0)return item._key, item._value
defpq_sort(C):"""Sort a collection of elements stored in a positional list."""
n =len(C)
P = HeapPriorityQueue
for j inrange(n):
element = C.delete(C.first())
P.add(int(str(element)),int(str(element)))# use element as key and valuefor j inrange(n):
k, v = P.remove_min()
C.add_last(v)# store smallest remaining element in Cif __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(2,'B')
priorityQueue.add(4,"C")
priorityQueue.add(5,"A")
priorityQueue.add(9,"F")
priorityQueue.add(15,"K")
priorityQueue.add(6,"Z")
priorityQueue.add(7,"Q")
9.47
import numpy as np
defpickSort(data):for i inrange(len(data)):min= i
for j inrange(i+1,len(data)):if data[j]< data[min]:min= j
data[i],data[min]= data[min],data[i]return data
if __name__ =='__main__':
target = np.random.randint(0,100,size=10)print(pickSort(list(target)))pass
9.48
import numpy as np
definsertSort(data):for i inrange(1,len(data)):while i >0and data[i]< data[i -1]:
data[i], data[i -1]= data[i -1], data[i]
i -=1return data
passif __name__ =='__main__':
target = np.random.randint(0,100, size=10)print(insertSort(list(target)))
9.49
import math
import numpy as np
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
deftoString(self):return self._data
def_heapify(self, index):
largest = index
lchild =2*largest +1
rchild =2* largest +2if lchild < trailer and self._data[lchild]< self._data[largest]:
largest = lchild
if rchild < trailer and self._data[rchild]< self._data[largest]:
largest = rchild
if largest != index:
self._swap(index,largest)
self._heapify(largest)defheapSort(self):global trailer
trailer = self._n
for i inrange(self._n-1,0,-1):
self._swap(0,i)
trailer -=1
self._heapify(0)if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
priorityQueue.add(7,'B')
priorityQueue.add(4,"C")
priorityQueue.add(6,"A")
priorityQueue.add(11,"F")
priorityQueue.add(917,"F")
priorityQueue.add(23,"F")
priorityQueue.add(76,"F")
priorityQueue.add(34,"F")
priorityQueue.add(29,"F")
priorityQueue.add(87,"F")
priorityQueue.add(65,"F")
priorityQueue.add(12,"F")print(priorityQueue)
priorityQueue.heapSort()print(priorityQueue)
9.53
import time
import numpy as np
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]< self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]< self._data[left]:
small_child = right
if self._data[small_child]< self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
deftoString(self):return self._data
def_heapify(self, index):
largest = index
lchild =2* largest +1
rchild =2* largest +2if lchild < trailer and self._data[lchild]< self._data[largest]:
largest = lchild
if rchild < trailer and self._data[rchild]< self._data[largest]:
largest = rchild
if largest != index:
self._swap(index, largest)
self._heapify(largest)defSwap(self, data, i, j):
data[i], data[j]= data[j], data[i]defHeapify(self, data, i):
largest = i
lchild =2* largest +1
rchild =2* largest +2if lchild < trailer and data[lchild]< data[largest]:
largest = lchild
if rchild < trailer and data[rchild]< data[largest]:
largest = rchild
if largest != i:
self.Swap(data, i, largest)
self.Heapify(data,largest)defheapSort1(self):
data =[]
temp = self._data.copy()global trailer
trailer = self._n
for i inrange(len(temp)-1,0,-1):
self.Swap(temp,0, i)
trailer -=1
self.Heapify(temp,0)
data.append(temp.pop())return data.reverse()defheapSort2(self):global trailer
trailer = self._n
for i inrange(self._n -1,0,-1):
self._swap(0, i)
trailer -=1
self._heapify(0)if __name__ =='__main__':
priorityQueue = HeapPriorityQueue()
N =100for i inrange(N):
priorityQueue.add(key=np.random.randint(1,100, size=1), value=np.random.random())
start = time.time()
priorityQueue.heapSort1()
send = time.time()print(f"非原地排序 : {send - start}s")
priorityQueue.heapSort2()print(priorityQueue)print(f'原地排序: {time.time() - send}s')#实验证明很奇怪,为什么开辟了一个新的空间反而更快?
9.54
import math
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]> self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]> self._data[left]:
small_child = right
if self._data[small_child]> self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
passdef_heapify(self, index):
largest = index
lchild =2* largest +1
rchild =2* largest +2if lchild < trailer and self._data[lchild]> self._data[largest]:
largest = lchild
if rchild < trailer and self._data[rchild]> self._data[largest]:
largest = rchild
if largest != index:
self._swap(index, largest)
self._heapify(largest)defheapSort(self):global trailer
trailer = self._n
for i inrange(self._n -1,0,-1):
self._swap(0, i)
trailer -=1
self._heapify(0)classFavoritesListMTF(HeapPriorityQueue):deftop(self, k):ifnot1<= k <=len(self):raise ValueError("illegel value for k ")
self.heapSort()for i inrange(k):
key,value = self._data[i]._key,self._data[i]._value
yield key,value
if __name__ =='__main__':
favoritesListMTF = FavoritesListMTF()
favoritesListMTF.add(2,'B')
favoritesListMTF.add(4,"C")
favoritesListMTF.add(5,"A")
favoritesListMTF.add(11,"F")
favoritesListMTF.add(917,"F")
favoritesListMTF.add(23,"F")
favoritesListMTF.add(76,"F")
favoritesListMTF.add(34,"F")
favoritesListMTF.add(29,"F")
favoritesListMTF.add(87,"F")
favoritesListMTF.add(65,"F")
favoritesListMTF.add(12,"F")for favorites in favoritesListMTF.top(5):print(favorites)
9.58
import math
import numpy as np
from collections import deque
classEmpty(Exception):passclassPriorityQueueBase:"""Abstract base class for a priority queue."""class_Item:"""Lightweight composite to store priority."""
__slots__ ="_key",'_value'def__init__(self, key, value):
self._key = key
self._value = value
def__lt__(self, other):return self._key < other._key
defis_empty(self):"""Return True if the priority queue is empty."""returnlen(self)==0classHeapPriorityQueue(PriorityQueueBase):"""A min-oriented priority queue implemented with a binary heap."""def__init__(self):
self._data =[]
self._n =0
self._trailer =Nonedef_parent(self, j):return(j -1)//2def_left(self, j):return2* j +1def_right(self, j):return2* j +2def_has_left(self, j):return self._left(j)< self._n
def_has_right(self, j):return self._right(j)< self._n
def_swap(self, i, j):
self._data[i], self._data[j]= self._data[j], self._data[i]def_uphead(self, j):
now = j
parent = self._parent(now)while parent >=0and now >0:if self._data[now]> self._data[parent]:
self._swap(now, parent)
now = parent
parent = self._parent(now)def_downheap(self, j):
now = j
history =None
small_child =Nonewhile history != now:
history = now
if self._has_left(now):
left = self._left(now)
small_child = left
if self._has_right(now):
right = self._right(now)if self._data[right]> self._data[left]:
small_child = right
if self._data[small_child]> self._data[now]:
self._swap(now, small_child)
now = small_child
def__len__(self):"""Return the number of items in the priority queue."""return self._n
defadd(self, key, value):"""Add a key-value pair to the priority queue."""
items = self._Item(key, value)
self._data.append(items)
self._n +=1
self._uphead(self._n -1)
self._trailer = self._data[-1]defmin(self):"""Return but do not remove (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
item = self._data[0]return item._key
defremove_min(self):"""Remove and return (k,v) tuple with minimum key.
Raise Empty exception if empty.
"""if self.is_empty():raise Empty("Priority queue is empty.")
self._swap(0,len(self._data)-1)# put minimum item at the end
item = self._data.pop()# and remove it from the list.
self._n -=1
self._downheap(0)
self._trailer = self._data[-1]return item._key, item._value
def__str__(self):return' '.join(str(items._key)+","+str(items._value)for items in self._data)deffind_all_min(self, key):
root =0
data = deque()
data.append(root)
result =[]whilelen(data)!=0:
node = data.popleft()if self._data[node]._key > key:passelse:
result.append(node)if self._has_left(node):
data.append(self._left(node))if self._has_right(node):
data.append(self._right(node))return" ".join(str(self._data[i]._key)for i in result)defheappushpop(self, key, value):
nowKey, nowValue = self.min()
items = self._Item(key, value)if nowKey < key:
self._data =[items]+ self._data[:]
self._trailer = self._data[-1]return nowKey
else:
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._Item(key, value)
pop = self._data[0]
self._data[0]= items
return pop._key, pop._value
passdef_heapify(self, index):
largest = index
lchild =2* largest +1
rchild =2* largest +2if lchild < trailer and self._data[lchild]> self._data[largest]:
largest = lchild
if rchild < trailer and self._data[rchild]> self._data[largest]:
largest = rchild
if largest != index:
self._swap(index, largest)
self._heapify(largest)defheapSort(self):global trailer
trailer = self._n
for i inrange(self._n -1,0,-1):
self._swap(0, i)
trailer -=1
self._heapify(0)classAdaptPriorityQueue:def__init__(self, data):
self._array = HeapPriorityQueue()
self._temp = data # 原数组
self._n =len(data)def__len__(self):return self._n
definitializeData(self):
heapify =[]# 存放排序好的数组for array in self._temp:
self._array.add(array,array)for array in self._array._data:
heapify.append(array._key)return heapify
defheapify(self):
array = self.initializeData()return array
defheappush(self, e):
self._array.add(e, e)
self._n +=1defheappop(self):print(self._array.remove_min())
self._n -=1defheappushpop(self, key, value):
nowKey, nowValue = self._array.min()
items = self._array._Item(key, value)if nowKey < key:
self._array._data =[items]+ self._array._data[:]
self._array.trailer = self._array._data[-1]return nowKey
else:
pop = self._array._data[0]
self._array._data[0]= items
return pop._key, pop._value
defheapreplace(self, key, value):
items = self._array._Item(key, value)
pop = self.array._data[0]
self._array._data[0]= items
return pop._key, pop._value
if __name__ =='__main__':
np.random.seed(100)
data =list(np.random.randint(1,100, size=10))
adaptPriorityQueue = AdaptPriorityQueue(data)print(data)print(adaptPriorityQueue.heapify())
9.5class Empty(Exception): passclass _DoublyLinkedBase: """A base class providing a doubly linked list representation.""" class _Node: """Lightweight,nonpublic class for storing a doubly linked node.""" __slots__ = "_elemen