Guest User

Lab 07 solutions

a guest
Mar 16th, 2015
316
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.25 KB | None | 0 0
  1. class LLNode:
  2. '''Node to be used in linked list
  3.  
  4. nxt: LLNode -- next node
  5. None iff we're at end of list
  6. value: object --- data for current node
  7. '''
  8.  
  9. def __init__(self, value, nxt=None):
  10. ''' (LLNode, object, LLNode) -> NoneType
  11.  
  12. Create LLNode (self) with data value and successor nxt.
  13. '''
  14. self.value, self.nxt = value, nxt
  15.  
  16. def __repr__(self):
  17. ''' (LLNode) -> str
  18.  
  19. Return a string representation of LLNode (self) that can yields
  20. an equivalent LLNode if evaluated in Python.
  21.  
  22. >>> n = LLNode(5, LLNode(7))
  23. >>> n.nxt
  24. LLNode(7)
  25. >>> n
  26. LLNode(5, LLNode(7))
  27. '''
  28. if self.nxt is None:
  29. return 'LLNode({})'.format(repr(self.value))
  30. else:
  31. return 'LLNode({}, {})'.format(repr(self.value), repr(self.nxt))
  32.  
  33. def __str__(self):
  34. ''' (LLNode) -> str
  35.  
  36. Return a user-friendly representation of this LLNode.
  37.  
  38. >>> n = LLNode(5, LLNode(7))
  39. >>> print(n)
  40. 5 -> 7 ->|
  41. '''
  42. if self.nxt is None:
  43. return '{} ->|'.format(str(self.value))
  44. else:
  45. return '{} -> {}'.format(str(self.value), str(self.nxt))
  46.  
  47. def __eq__(self, other):
  48. ''' (LLNode, object) -> bool
  49.  
  50. Return whether LLNode (self) is equivalent to other.
  51.  
  52. >>> LLNode(5).__eq__(5)
  53. False
  54. >>> n = LLNode(5, LLNode(7))
  55. >>> n2 = LLNode(5, LLNode(7, None))
  56. >>> n.__eq__(n2)
  57. True
  58. '''
  59. return (type(self) == type(other) and
  60. (self.value, self.nxt) == (other.value, other.nxt))
  61.  
  62.  
  63. class LinkedList:
  64. '''Collection of LLNodes organized into a linked list.
  65.  
  66. front: LLNode -- front of list
  67. back: LLNode -- back of list'''
  68.  
  69. def __init__(self):
  70. ''' (LinkedList) -> NoneType
  71.  
  72. Create an empty linked list.
  73. '''
  74. self.front, self.back = None, None
  75. self.size = 0
  76.  
  77. def __str__(self):
  78. ''' (LinkedList) -> str
  79.  
  80. Return a human-friendly string representation of
  81. LinkedList (self)
  82.  
  83. >>> lnk = LinkedList()
  84. >>> lnk.prepend(5)
  85. >>> print(lnk)
  86. 5 ->|
  87. '''
  88. return str(self.front)
  89.  
  90. def __eq__(self, other):
  91. ''' (LinkedList, object) -> bool
  92.  
  93. Return whether LinkedList (self) is equivalent to
  94. other.
  95.  
  96. >>> LinkedList().__eq__(None)
  97. False
  98. >>> lnk = LinkedList()
  99. >>> lnk.prepend(5)
  100. >>> lnk2 = LinkedList()
  101. >>> lnk2.prepend(5)
  102. >>> lnk.__eq__(lnk2)
  103. True
  104. '''
  105. return (type(self) == type(other) and
  106. (self.size, self.front) == (other.size, other.front))
  107.  
  108. def append(lnk, value):
  109. ''' (LinkedList, object) -> NoneType
  110.  
  111. Insert a new node with value at back of lnk.
  112.  
  113. >>> lnk = LinkedList()
  114. >>> lnk.append(5)
  115. >>> lnk.size
  116. 1
  117. >>> print(lnk.front)
  118. 5 ->|
  119. >>> lnk.append(6)
  120. >>> lnk.size
  121. 2
  122. >>> print(lnk.front)
  123. 5 -> 6 ->|
  124. '''
  125. new_node = LLNode(value)
  126. if lnk.back:
  127. lnk.back.nxt = new_node
  128. lnk.back = new_node
  129. else:
  130. lnk.back = lnk.front = new_node
  131. lnk.size += 1
  132.  
  133. def prepend(self, value):
  134. ''' (LinkedList, object) -> Nonetype
  135.  
  136. Insert value at front of LLNode (self).
  137.  
  138. >>> lnk = LinkedList()
  139. >>> lnk.prepend(0)
  140. >>> lnk.prepend(1)
  141. >>> lnk.prepend(2)
  142. >>> str(lnk.front)
  143. '2 -> 1 -> 0 ->|'
  144. >>> lnk.size
  145. 3
  146. '''
  147. self.front = LLNode(value, self.front)
  148. if self.back is None:
  149. self.back = self.front
  150. self.size += 1
  151.  
  152. def delete_front(self):
  153. ''' (LinkedList) -> NoneType
  154.  
  155. Delete front node from LinkedList (self).
  156.  
  157. self.front must not be None
  158.  
  159. >>> lnk = LinkedList()
  160. >>> lnk.prepend(0)
  161. >>> lnk.prepend(1)
  162. >>> lnk.prepend(2)
  163. >>> lnk.delete_front()
  164. >>> str(lnk.front)
  165. '1 -> 0 ->|'
  166. >>> lnk.size
  167. 2
  168. '''
  169.  
  170. self.front = self.front.nxt
  171. self.size -= 1
  172.  
  173. def __getitem__(self, index):
  174. ''' (LinkedList, int|slice) -> object
  175.  
  176. Return the value at position index.
  177. # don't fuss about slices yet.
  178.  
  179. >>> lnk = LinkedList()
  180. >>> lnk.prepend(1)
  181. >>> lnk.prepend(0)
  182. >>> lnk.__getitem__(1)
  183. 1
  184. '''
  185. if index > self.size - 1:
  186. raise Exception('out of range')
  187. else:
  188. current_node = self.front
  189. for i in range(0, index):
  190. current_node = current_node.nxt
  191. return current_node.value
  192.  
  193.  
  194. def __setitem__(self, index, value):
  195. ''' (LinkedList, int|slice, object) -> NoneType
  196.  
  197. Set the value at index to value, if index is in range, otherwise
  198. raise an IndexError. Indexs are counted from 0. Note that negative
  199. integers can be adjusted by adding self.size, to get a index in
  200. range.
  201.  
  202. >>> lnk = LinkedList()
  203. >>> lnk.prepend(5)
  204. >>> lnk.prepend(7)
  205. >>> lnk.__setitem__(1, 9)
  206. >>> print(lnk.front)
  207. 7 -> 9 ->|
  208. >>> lnk[0] = 3
  209. >>> print(lnk.front)
  210. 3 -> 9 ->|
  211. >>> lnk[-1] = 8
  212. >>> print(lnk.front)
  213. 3 -> 8 ->|
  214. '''
  215. if index > self.size - 1:
  216. raise IndexError('index out of range')
  217. elif index < 0:
  218. index = index + self.size
  219. current_node = self.front
  220. for i in range(0, index):
  221. current_node = current_node.nxt
  222. current_node.value = value
  223.  
  224.  
  225.  
  226. def __contains__(self, value):
  227. ''' (LinkedList, object) -> bool
  228.  
  229. Return whether LinkedList (self) contains value.
  230.  
  231. >>> lnk = LinkedList()
  232. >>> lnk.prepend(0)
  233. >>> lnk.prepend(1)
  234. >>> lnk.prepend(2)
  235. >>> lnk.__contains__(1)
  236. True
  237. >>> lnk.__contains__(3)
  238. False
  239. '''
  240. current_node = self.front
  241. while current_node:
  242. if value == current_node.value:
  243. return True
  244. current_node = current_node.nxt
  245. return False
  246.  
  247. def __add__(self, other):
  248. ''' (LinkedList, LinkedList) -> LinkedList
  249.  
  250. Concatenate LinkedList (self) to LinkedList (other) and
  251. return a new list, leaving self and other unchanged.
  252.  
  253. >>> lnk1 = LinkedList()
  254. >>> lnk1.prepend(5)
  255. >>> lnk2 = LinkedList()
  256. >>> lnk2.prepend(7)
  257. >>> lnk3 = lnk1.__add__(lnk2)
  258. >>> print(lnk3.front)
  259. 5 -> 7 ->|
  260. >>> print(lnk1.front)
  261. 5 ->|
  262. >>> print(lnk2.front)
  263. 7 ->|
  264. '''
  265. new = LinkedList()
  266. current_node = self.front
  267. while current_node:
  268. new.append(current_node.value)
  269. current_node = current_node.nxt
  270. current_node = other.front
  271. while current_node:
  272. new.append(current_node.value)
  273. current_node = current_node.nxt
  274. return new
  275.  
  276. def insert_before(lnk, v1, v2):
  277. ''' (LinkedList, object, object) -> NoneType
  278.  
  279. Insert a new node with value v1 before the first occurrence
  280. of a node with value v2. Do nothing if no node has value
  281. v2.
  282.  
  283. >>> lnk = LinkedList()
  284. >>> lnk.prepend(5)
  285. >>> insert_before(lnk, 4, 5)
  286. >>> print(lnk.front)
  287. 4 -> 5 ->|
  288. >>> insert_before(lnk, 3, 5)
  289. >>> print(lnk.front)
  290. 4 -> 3 -> 5 ->|
  291. >>> insert_before(lnk, 3, 7)
  292. >>> print(lnk)
  293. 4 -> 3 -> 5 ->|
  294. '''
  295. if lnk.size > 0:
  296. prev_node = None
  297. cur_node = lnk.front
  298. while cur_node and not cur_node.value == v2:
  299. prev_node = cur_node
  300. cur_node = cur_node.nxt
  301. if cur_node:
  302. cur_node = LLNode(v1, cur_node)
  303. if prev_node is None:
  304. lnk.front = cur_node
  305. else:
  306. prev_node.nxt = cur_node
  307. lnk.size += 1
  308.  
  309. def delete_after(lnk, value):
  310. ''' (LinkedList, object) -> NoneType
  311.  
  312.  
  313. Delete node with value after the first occurrence of a
  314. node containing value, if possible.
  315.  
  316. >>> lnk = LinkedList()
  317. >>> lnk.append(3)
  318. >>> lnk.append(5)
  319. >>> lnk.append(7)
  320. >>> lnk.append(9)
  321. >>> delete_after(lnk, 3)
  322. >>> print(lnk)
  323. 3 -> 7 -> 9 ->|
  324. >>> delete_after(lnk, 7)
  325. >>> print(lnk)
  326. 3 -> 7 ->|
  327. >>> delete_after(lnk, 15)
  328. >>> print(lnk)
  329. 3 -> 7 ->|
  330. '''
  331. if lnk.front:
  332. current_node = lnk.front
  333. while current_node and not current_node.value == value:
  334. current_node = current_node.nxt
  335. if current_node and current_node.nxt:
  336. if lnk.back == current_node.nxt:
  337. lnk.back = current_node
  338. current_node.nxt = current_node.nxt.nxt
  339. lnk.size -= 1
  340.  
  341. def delete_back(lnk):
  342. ''' (LinkedList) -> NoneType
  343.  
  344. Delete back node of lnk, if it exists, otherwise
  345. do nothing.
  346.  
  347. >>> lnk = LinkedList()
  348. >>> lnk.prepend(5)
  349. >>> lnk.prepend(7)
  350. >>> print(lnk.front)
  351. 7 -> 5 ->|
  352. >>> delete_back(lnk)
  353. >>> lnk.size
  354. 1
  355. >>> print(lnk.front)
  356. 7 ->|
  357. >>> delete_back(lnk)
  358. >>> lnk.size
  359. 0
  360. >>> print(lnk.front)
  361. None
  362. '''
  363.  
  364. if lnk.size > 0:
  365. prev_node, cur_node = None, lnk.front
  366. # walk along until cur_node is lnk.back
  367. while cur_node.nxt:
  368. prev_node = cur_node
  369. cur_node = cur_node.nxt
  370. lnk.back = prev_node
  371. if lnk.back is None:
  372. lnk.front = None
  373. else:
  374. lnk.back.nxt = None
  375. lnk.size -= 1
  376.  
  377.  
  378.  
  379.  
  380.  
  381. def odd_nodes(lnk):
  382. ''' (LinkedList) -> LinkedList
  383.  
  384. Return a new linked list with values of odd-indexed nodes of lnk.
  385.  
  386. >>> lnk = LinkedList()
  387. >>> lnk.append(3)
  388. >>> lnk.append(5)
  389. >>> lnk.append(7)
  390. >>> lnk.append(9)
  391. >>> lnk2 = odd_nodes(lnk)
  392. >>> print(lnk2)
  393. 5 -> 9 ->|
  394. '''
  395.  
  396. new = LinkedList()
  397. current_node = lnk.front
  398. index = 0
  399. while current_node:
  400. if index % 2 == 1:
  401. new.append(current_node.value)
  402. index += 1
  403. current_node = current_node.nxt
  404. return new
  405.  
  406. def filter_nodes(lnk, f):
  407. ''' (LinkedList, function) -> LinkedList
  408.  
  409. Return a new linked list with values of lnk for
  410. nodes that satisfy boolean-valued function f.
  411.  
  412. >>> lnk = LinkedList()
  413. >>> lnk.append(3)
  414. >>> lnk.append(4)
  415. >>> lnk.append(5)
  416. >>> lnk.append(6)
  417. >>> def f(node): return node.value % 2 == 0
  418. >>> lnk2 = filter_nodes(lnk, f)
  419. >>> print(lnk2)
  420. 4 -> 6 ->|
  421. '''
  422. new_list, cur_node = LinkedList(), lnk.front
  423. while cur_node:
  424. if f(cur_node):
  425. #print(cur_node)
  426. new_list.append(cur_node.value)
  427. cur_node = cur_node.nxt
  428. return new_list
  429.  
  430. if __name__ == '__main__':
  431. import doctest
  432. doctest.testmod()
Advertisement
Add Comment
Please, Sign In to add comment