class Scoreboard(object): """ Fixed-length sequence of high scores in nondecreasing order.""" def __init__(self, capacity=10): """ Initialize scoreboard with given maximum capacity.""" self._board = SinglyLinkedList() self._cap = capacity def __len__(self): return len(self._board) def __getitem__(self, k): """ Return entry index k.""" if k == 0: return self._board.head() if k == len(self) - 1: return self._board.tail() if k > len(self) - 1 or k < 0: raise IndexError('Index is out of range') else: walk = self._board._head for _ in range(k): walk = walk._next return walk._element def add(self, entry): """ Consider adding entry to high scores.""" score = entry.get_score() # insert first element if len(self) == 0: self._board.add_first(entry) return good = score > self._board.head().get_score() or len(self) < self._cap if good: # insert an element to self._board prev = walk = self._board._head while walk is not None: if walk._element.get_score() > score: break else: prev = walk walk = walk._next prev._next = self._board._Node(entry, walk) self._board._size += 1 if walk is None: self._board._tail = prev._next # make the lenght of self._board to capacity if len(self) > self._cap: self._board.remove_first() return def __repr__(self): """ String representation of the scoreboard.""" s = '' walk = self._board._head while walk is not None: s += str(walk._element.get_score()) + ',' walk = walk._next return s[:-1]
def merge(left, right): """ Merges two linked lists, sorting by data in nodes Returns a new, merged list Runs in O(n) time """ # Create a new linked list that contains nodes from # merging left and right merged = SinglyLinkedList() # Add a fake head that is discarded later merged.add(0) # Set current to the head of the linked list current = merged.head # Obtain head nodes for left and right linked lists left_head = left.head right_head = right.head # Iterate over left and right until we reach the tail node # of either while left_head or right_head: # If the head node of left is None, we're past the tail # Add the node from right to merged linked list if left_head is None: current.next_node = right_head # Call next on right to set loop condition to False right_head = right_head.next_node # If the head node of right is None, we're past the tail # Add the tail node from left to merged linked list elif right_head is None: current.next_node = left_head # Call next on left to set loop condition to False left_head = left_head.next_node else: # Not at either tail node # Obtain node data to perform comparison operations left_data = left_head.data right_data = right_head.data # If data on left is less than right, set current to left node if left_data < right_data: current.next_node = left_head # Move left head to next node left_head = left_head.next_node # If data on left is greater than right, set current to right node else: current.next_node = right_head # Move right head to next node right_head = right_head.next_node # Move current to next node current = current.next_node # Discard fake head and set first merged node as head head = merged.head.next_node merged.head = head return merged
class LeakyStack(object): """ Implementation of a leaky stack based on singly linked list. When push is invoked with the stack at full capacity, accept the pushed element at the top while “leaking” the oldest element from the bottom of the stack to make room. """ def __init__(self, maxlen): super(LeakyStack, self).__init__() self._maxlen = maxlen self._data = SinglyLinkedList() self._size = 0 def __len__(self): """Return the number of elements in the stack.""" return self._size def is_empty(self): """Return True if the stack is empty.""" return self._size == 0 def push(self, e): """Add element e to the top of the stack. When stack is full, drop the bottom element to make room for new element. """ self._data.add_first(e) if self._size < self._maxlen: self._size += 1 elif self._size <= len(self._data) // 2: self._resize() def _resize(self): """ Delete the elements that not in the stack.""" self._data.cut(self._size) def pop(self): """Remove and return the element from the top of the stack (i.e., LIFO). Raise Empty exception if the stack is empty. """ if self.is_empty(): raise Empty('Leaky stack is empty!') rlt = self._data.remove_first() self._size -= 1 return rlt def top(self): """ Return (but do not remove) the element at the top of the stack. Raise Empty exception if the stack is empty. """ if self.is_empty(): raise Empty('Leaky stack is empty!') return self._data.head()
def split(linked_list): """ Divide the unsorted list at midpoint into sublists Takes O(k log n) time """ if linked_list == None or linked_list.head == None: left_half = linked_list right_half = None return left_half, right_half else: size = linked_list.size() mid = size // 2 mid_node = linked_list.node_at_index(mid - 1) left_half = linked_list right_half = SinglyLinkedList() right_half.head = mid_node.next_node mid_node.next_node = None return left_half, right_half
current.next = previous previous = current current = next return previous def reverse_linked_list_recursive(head): if head.next is None: return head temp = reverse_linked_list_recursive(head.next) head.next.next = head head.next = None return temp if __name__ == '__main__': lst = SinglyLinkedList() lst.append('0') lst.append('1') lst.append('2') lst.append('3') lst.head = reverse_linked_list(lst.head) lst.head = reverse_linked_list_recursive(lst.head) print(lst)