Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.31 KB | None | 0 0
  1. # BST (OOP Array/FreeSlot Linked List Implementation) -----------#
  2.  
  3. class Node:
  4.  
  5. def __init__(self, data, ptr, leftPtr, rightPtr):
  6. self._data = data
  7. self._ptr = ptr
  8. self._leftPtr = leftPtr
  9. self._rightPtr = rightPtr
  10.  
  11. def get_data(self):
  12. return self._data
  13.  
  14. def get_ptr(self):
  15. return self._ptr
  16.  
  17. def get_leftPtr(self):
  18. return self._leftPtr
  19.  
  20. def get_rightPtr(self):
  21. return self._rightPtr
  22.  
  23. def set_data(self, data):
  24. self._data = data
  25.  
  26. def set_ptr(self, ptr):
  27. self._ptr = ptr
  28.  
  29. def set_leftPtr(self, leftPtr):
  30. self._leftPtr = leftPtr
  31.  
  32. def set_rightPtr(self, rightPtr):
  33. self._rightPtr = rightPtr
  34.  
  35. def __str__(self):
  36. return "Data Value: " + self._data + " , Pointer Value: " + str(self._ptr)
  37.  
  38. class BST:
  39. def __init__(self, size):
  40. self._tree = [Node('', i + 1, -1, -1) for i in range(size - 1)]
  41. self._tree.append(Node('', -1, -1, -1))
  42. self._root = -1
  43. self._nextFree = 0
  44.  
  45. def getFreeNode(self):
  46. if self._nextFree == -1:
  47. return 0
  48. else:
  49. temp = self._nextFree
  50. self._nextFree = self._tree[temp].get_ptr()
  51. self._tree[temp].set_ptr(0)
  52. return temp
  53.  
  54. def returnNode(self, ptr):
  55.  
  56. # begin: add to nextFree linked list
  57. node = self._tree[ptr]
  58. node.set_ptr(self._nextFree)
  59. self._nextFree = ptr
  60. # end: add to nextFree linked list
  61.  
  62. # begin: 'reset' node
  63. node.set_data('')
  64. node.set_leftPtr(-1)
  65. node.set_rightPtr(-1)
  66. # end: 'reset' node
  67.  
  68. def addNode(self, newItem):
  69.  
  70. if self._nextFree == -1:
  71. return
  72.  
  73. else:
  74.  
  75. # begin: set data to free node
  76. free_pos = self.getFreeNode()
  77. free_node = self._tree[free_pos]
  78. free_node.set_data(newItem)
  79. # end: set data to free node
  80.  
  81. # begin: assign free node to correct branch of BST
  82. if self._root == -1:
  83. self._root = free_pos
  84.  
  85. else:
  86.  
  87. # begin: traverse the tree until the free position is found
  88. def helper(curr, data):
  89. curr_data = self._tree[curr].get_data()
  90.  
  91. if data > curr_data:
  92. rightPtr = self._tree[curr].get_rightPtr()
  93.  
  94. # found it
  95. if rightPtr == -1:
  96. self._tree[curr].set_rightPtr(free_pos)
  97.  
  98. else:
  99. helper(rightPtr, data)
  100.  
  101. else:
  102. leftPtr = self._tree[curr].get_leftPtr()
  103.  
  104. # found it
  105. if leftPtr == -1:
  106. self._tree[curr].set_leftPtr(free_pos)
  107.  
  108. else:
  109. helper(leftPtr, data)
  110.  
  111. helper(self._root, newItem)
  112. # end: traverse the tree until the free position is found
  113.  
  114. # end: assign free node to correct branch of BST
  115.  
  116. def deleteRoot(self):
  117.  
  118. if self._root == -1:
  119. return
  120.  
  121. root_node = self._tree[self._root]
  122.  
  123. # begin: simple cases
  124. if root_node.get_leftPtr() == -1 and root_node.get_rightPtr() == -1:
  125. self.returnNode(self._root)
  126. self._root = -1
  127.  
  128. elif root_node.get_leftPtr() == -1 and root_node.get_rightPtr() != -1:
  129. temp = self._root
  130. self._root = root_node.get_rightPtr()
  131. self.returnNode(temp)
  132.  
  133. elif root_node.get_rightPtr() == -1 and root_node.get_leftPtr() != -1:
  134. temp = self._root
  135. self._root = root_node.get_leftPtr()
  136. self.returnNode(temp)
  137. # end: simple cases
  138.  
  139. # begin: have both left and right child
  140. else:
  141.  
  142. # begin: find maximum of left subtree (and its parent)
  143. def findMax(root, prev):
  144. if self._tree[root].get_rightPtr() == -1:
  145. return [root, prev]
  146. else:
  147. return findMax(self._tree[root].get_rightPtr(), root)
  148.  
  149. [left_max, parent] = findMax(self._tree[self._root].get_leftPtr(), None)
  150. # end: find maximum of left subtree (and its parent)
  151.  
  152. # begin: set root to be maximum of left subtree
  153. self._tree[left_max].set_rightPtr(root_node.get_rightPtr())
  154.  
  155. if parent:
  156. # successor is a right child
  157.  
  158. # right child of parent <-- left child of successor
  159. self._tree[parent].set_rightPtr(self._tree[left_max].get_leftPtr())
  160.  
  161. # left child of successor <-- left child of root
  162. self._tree[left_max].set_leftPtr(root_node.get_leftPtr())
  163.  
  164. else:
  165. # successor is just the left child of root
  166. pass
  167.  
  168. temp = self._root
  169. self._root = left_max
  170. # end: set root to be maximum of left subtree
  171.  
  172. self.returnNode(temp)
  173. # end: have both left and right child
  174.  
  175. def height(self):
  176.  
  177. def helper(curr):
  178. if curr == -1:
  179. return -1
  180. else:
  181. return max(1 + helper(self._tree[curr].get_leftPtr()),\
  182. 1 + helper(self._tree[curr].get_rightPtr()))
  183.  
  184. return helper(self._root)
  185.  
  186. def childCount(self):
  187.  
  188. # Returns the total number of nodes in the logical BST that has only 1 child.
  189. # If there is no node in the logical BST, it returns 0.
  190.  
  191. def helper(curr):
  192. if self._root == -1:
  193. return 0
  194.  
  195. elif curr.get_leftPtr() == -1 and curr.get_rightPtr() != -1:
  196. return 1
  197.  
  198. elif curr.get_rightPtr() == -1 and curr.get_leftPtr() != -1:
  199. return 1
  200.  
  201. elif curr.get_leftPtr() != -1 and curr.get_rightPtr() != -1:
  202. return helper(self._tree[curr.get_leftPtr()]) + \
  203. helper(self._tree[curr.get_rightPtr()])
  204.  
  205. else:
  206. return 0
  207.  
  208. return helper(self._tree[self._root])
  209.  
  210. def reverseTraversal(self):
  211.  
  212. to_ret = []
  213.  
  214. def helper(curr):
  215.  
  216. nonlocal to_ret
  217.  
  218. # right (biggest)
  219. if curr.get_rightPtr() != -1:
  220. helper(self._tree[curr.get_rightPtr()])
  221.  
  222. # root
  223. to_ret.append(curr.get_data())
  224.  
  225. # left (smallest)
  226. if curr.get_leftPtr() != -1:
  227. helper(self._tree[curr.get_leftPtr()])
  228.  
  229. helper(self._tree[self._root])
  230.  
  231. return to_ret
  232.  
  233. def inOrderTraversal(self):
  234.  
  235. if self._root == -1:
  236. return []
  237.  
  238. to_ret = []
  239.  
  240. def helper(curr):
  241.  
  242. nonlocal to_ret
  243.  
  244. # left (smallest)
  245. if curr.get_leftPtr() != -1:
  246. helper(self._tree[curr.get_leftPtr()])
  247.  
  248. # root
  249. to_ret.append(curr.get_data())
  250.  
  251. # right (biggest)
  252. if curr.get_rightPtr() != -1:
  253. helper(self._tree[curr.get_rightPtr()])
  254.  
  255. helper(self._tree[self._root])
  256.  
  257. return to_ret
  258.  
  259. def preOrderTraversal(self):
  260.  
  261. to_ret = []
  262.  
  263. def helper(curr):
  264.  
  265. nonlocal to_ret
  266.  
  267. # root
  268. to_ret.append(curr.get_data())
  269.  
  270. # left
  271. if curr.get_leftPtr() != -1:
  272. helper(self._tree[curr.get_leftPtr()])
  273.  
  274. # right
  275. if curr.get_rightPtr() != -1:
  276. helper(self._tree[curr.get_rightPtr()])
  277.  
  278. helper(self._tree[self._root])
  279.  
  280. return to_ret
  281.  
  282. def postOrderTraversal(self):
  283.  
  284. to_ret = []
  285.  
  286. def helper(curr):
  287.  
  288. nonlocal to_ret
  289.  
  290. # left
  291. if curr.get_leftPtr() != -1:
  292. helper(self._tree[curr.get_leftPtr()])
  293.  
  294. # right
  295. if curr.get_rightPtr() != -1:
  296. helper(self._tree[curr.get_rightPtr()])
  297.  
  298. # root
  299. to_ret.append(curr.get_data())
  300.  
  301.  
  302. helper(self._tree[self._root])
  303.  
  304. return to_ret
  305.  
  306. def displayArray(self):
  307. print("next free", self._nextFree)
  308. print('root', self._root)
  309. for i in range(len(self._tree)):
  310. print ("Slot Number "+ str(i) + " " + str(self._tree[i]) + \
  311. ' leftPtr: ' + str(self._tree[i]._leftPtr) + \
  312. ' rightPtr: ' + str(self._tree[i]._rightPtr))
  313.  
  314. def test1():
  315. BT = BST(7)
  316. BT.addNode("Dave")
  317. BT.addNode("Fred")
  318. BT.addNode("Ed")
  319. BT.addNode("Greg")
  320. BT.addNode("Bob")
  321. BT.addNode("Cid")
  322. BT.addNode("John")
  323. BT.addNode("Ali") #not added because it is the 8th node
  324. return BT.inOrderTraversal() == ['Bob', 'Cid', 'Dave', 'Ed', 'Fred', 'Greg', 'John'] and BT.height() == 3
  325.  
  326.  
  327. def test2():
  328. BT = BST(7)
  329. BT.addNode("Dave")
  330. BT.addNode("Fred")
  331. BT.addNode("Ed")
  332. BT.addNode("Greg")
  333. BT.addNode("Bob")
  334. BT.addNode("Cid")
  335. BT.addNode("Ali")
  336. #Call for deleteRoot 8 times
  337. BT.deleteRoot()
  338. BT.deleteRoot()
  339. BT.deleteRoot()
  340. BT.deleteRoot()
  341. BT.deleteRoot()
  342. BT.deleteRoot()
  343. a = BT.height() # a = 0 because BST has only 1 node
  344. BT.deleteRoot()
  345. b = BT.height() # -1 No BST no height
  346. #BST is empty, deleteRoot() does nothing
  347. return BT.inOrderTraversal() == [] and a == 0 and b == -1
  348.  
  349. def test3():
  350. BT = BST(7)
  351. BT.addNode("Dave")
  352. BT.addNode("Fred")
  353. BT.addNode("Ed")
  354. BT.addNode("Greg")
  355. BT.addNode("Bob")
  356. BT.addNode("Cid")
  357. BT.addNode("Ali")
  358. #Call for deleteRoot 8 times
  359. BT.deleteRoot()
  360. BT.deleteRoot()
  361. BT.deleteRoot()
  362. BT.deleteRoot()
  363. BT.deleteRoot()
  364. BT.deleteRoot()
  365. BT.deleteRoot()
  366. BT.deleteRoot()
  367. #re-insert the items to ensure BST work again.
  368. BT.addNode("Dave")
  369. BT.addNode("Fred")
  370. BT.addNode("Ed")
  371. BT.addNode("Greg")
  372. BT.addNode("Bob")
  373. BT.addNode("Cid")
  374. BT.addNode("Ali")
  375. return BT.inOrderTraversal() == ['Ali', 'Bob', 'Cid', 'Dave', 'Ed', 'Fred', 'Greg']
  376.  
  377. print(test1())
  378. print(test2())
  379. print(test3())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement