Advertisement
Guest User

Untitled

a guest
Nov 25th, 2014
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.90 KB | None | 0 0
  1. """
  2. A Heap implemented by
  3. mapping a tree onto an array (Python list) of the same size.
  4. file: array_heap.py
  5. language: python3
  6. author: Matthew Fluet
  7. author: James Heliotis
  8. author: Arthur Nunes-Harwitt
  9. author: Ben K Steele
  10. author: Aaron T Deever
  11. author: Lilly Xie
  12. new language feature: passing (and storing) functions as arguments.
  13. """
  14.  
  15. import copy
  16. from rit_object import *
  17.  
  18. # Utility functions to map tree relations to array indices ###
  19.  
  20. def parent(i):
  21. """
  22. Return index of parent of node at index i.
  23. """
  24. return (i - 1)//2
  25.  
  26. def lChild(i):
  27. """
  28. Return index of left child of node at index i.
  29. """
  30. return 2*i + 1
  31.  
  32. def rChild(i):
  33. """
  34. Return index of right child of node at index i.
  35. """
  36. return 2*i + 2
  37.  
  38. ############################################################################
  39.  
  40. class Heap(rit_object):
  41. """
  42. A heap inside an array that may be bigger than the
  43. heapified section of said array
  44. SLOTS:
  45. array: the Python list object used to store the heap
  46. size: the number of array elements currently in the
  47. heap. (size-1) is the index of the last element.
  48. compareFunc: A function to compare values in the heap.
  49. For example, if compareFunc performs less-than,
  50. then the heap will be a min-heap.
  51. """
  52. __slots__ = ('array', 'size', 'compareFunc')
  53. _types = ( list, int, object)
  54.  
  55. def createEmptyHeap(maxSize, compareFunc):
  56. """
  57. createEmptyHeap : NatNum * Function -> Heap
  58. Create an empty heap with capacity maxSize
  59. and comparison function compareFunc.
  60. Return initialized heap.
  61. """
  62.  
  63. heap = Heap([None for _ in range(maxSize)],0, compareFunc)
  64. return heap
  65.  
  66. def displayHeap(heap, startIndex=0, indent=""):
  67. """
  68. displayHeap : Heap * NatNum * String -> NoneType
  69. Display the heap as a tree with each child value indented
  70. from its parent value. Traverse the tree in preorder.
  71. """
  72. if startIndex < heap.size:
  73. print(indent + str(heap.array[startIndex]))
  74. displayHeap(heap, lChild(startIndex), indent + ' ')
  75. displayHeap(heap, rChild(startIndex), indent + ' ')
  76.  
  77. def siftUp(heap, startIndex):
  78. """
  79. siftUp : Heap * NatNum -> NoneType
  80. Move the value at startIndex up to its proper spot in
  81. the given heap. Assume that the value does not have
  82. to move down.
  83. """
  84. i = startIndex
  85. a = heap.array
  86. while i > 0 and not heap.compareFunc(a[parent(i)], a[i]):
  87. (a[parent(i)], a[i]) = (a[i], a[parent(i)]) # swap
  88. i = parent(i)
  89.  
  90. def _first_of_3(heap, index):
  91. """
  92. _first_of_3 : Heap * NatNum -> NatNum
  93. _first_of_3 is a private, utility function.
  94. Look at the values at:
  95. - index
  96. - the left child position of index, if in the heap
  97. - the right child position of index, if in the heap
  98. and return the index of the value that should come
  99. first, according to heap.compareFunc().
  100. """
  101. lt = lChild(index)
  102. rt = rChild(index)
  103. thisVal = heap.array[index]
  104. if rt < heap.size: # If there are both left and right children
  105. lVal = heap.array[lt]
  106. rVal = heap.array[rt]
  107. if heap.compareFunc(lVal, thisVal) \
  108. or heap.compareFunc(rVal, thisVal):
  109. if heap.compareFunc(lVal, rVal):
  110. return lt # The left child goes first
  111. else:
  112. return rt # The right child goes first
  113. else:
  114. return index # This one goes first
  115. elif lt < heap.size: # If there is only a left child
  116. lVal = heap.array[lt]
  117. if heap.compareFunc(lVal, thisVal):
  118. return lt # The left child goes first
  119. else:
  120. return index # This one goes first
  121. else: # There are no children
  122. return index
  123.  
  124. def siftDown(heap, startIndex):
  125. """
  126. siftDown : Heap * NatNum -> NoneType
  127. Move the value at startIndex down to its proper spot in
  128. the given heap. Assume that the value does not have
  129. to move up.
  130. """
  131. curIndex = startIndex
  132. a = heap.array
  133. swapIndex = _first_of_3(heap, curIndex)
  134. while (swapIndex != curIndex):
  135. (a[swapIndex], a[curIndex]) = (a[curIndex], a[swapIndex]) # swap
  136. curIndex = swapIndex
  137. swapIndex = _first_of_3(heap, curIndex)
  138.  
  139. def add(heap, newValue):
  140. """
  141. add : Heap * Comparable -> NoneType
  142. add inserts the element at the correct position in the heap.
  143. """
  144. if heap.size == len(heap.array):
  145. heap.array = heap.array + ([None] * len(heap.array))
  146. heap.array[heap.size] = newValue
  147. siftUp(heap, heap.size)
  148. heap.size = heap.size + 1
  149.  
  150. def removeMin(heap):
  151. """
  152. removeMin : Heap -> Comparable
  153. removeMin removes and returns the minimum element in the heap.
  154. """
  155. res = heap.array[0]
  156. heap.size = heap.size - 1
  157. heap.array[0] = heap.array[heap.size]
  158. heap.array[heap.size] = None
  159. siftDown(heap, 0)
  160. return res
  161.  
  162. def updateValue(heap, index, newValue):
  163. """
  164. Fix the heap after changing the value in one of its nodes.
  165. """
  166. oldValue = heap.array[index]
  167. heap.array[index] = newValue
  168. if heap.compareFunc(newValue, oldValue):
  169. siftUp(heap, index)
  170. else:
  171. siftDown(heap, index)
  172.  
  173. def peek(heap):
  174. """
  175. peek : Heap -> Comparable
  176. peek returns a deep copy of the current root/top of the heap
  177. """
  178. res = copy.deepcopy(heap.array[0])
  179. return res
  180.  
  181. def less(a, b):
  182. """
  183. less : Comparable * Comparable -> Boolean
  184. This ordering function returns True if the first value is smaller.
  185. """
  186. return a <= b
  187.  
  188. def greater(a, b):
  189. """
  190. greater : Comparable * Comparable -> Boolean
  191. This ordering function returns True if the first value is larger.
  192. """
  193. return a >= b
  194.  
  195. ############################################################################
  196.  
  197.  
  198. def testHeap( testData ):
  199. """
  200. testHeap : TupleOfComparable -> NoneType
  201. Create a min heap, fill it with the test data, and display it.
  202. """
  203. print( "testHeap(", testData, "):" )
  204.  
  205. heap = createEmptyHeap(len(testData), less)
  206.  
  207. for i in range(len(testData)):
  208. add(heap, testData[i])
  209. if i % 2 == 0: print( i, "-th iteration's root:", peek( heap ) )
  210.  
  211. print("Heap size is now", heap.size)
  212. displayHeap(heap)
  213. print()
  214.  
  215. # Perform some heap modifications. Tests updateValue().
  216. for (index, value) in ((1, 100), (4, -1)):
  217. print("Change value at position", index, "to", value)
  218. updateValue(heap, index, value)
  219. displayHeap(heap)
  220. print( "current root:", peek( heap ) )
  221.  
  222. if __name__ == '__main__':
  223.  
  224. testData = (1, 3, 5, 7, 9, 10, 8, 6, 4, 2, 0) # Test data
  225. testHeap( testData )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement