Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Computer Science 112 Fundamentals of Programming II Lists Lists: Formal Properties • A list is a linear collection that supports access, replacement, insertion, and removal at any position • Lists are more general-purpose than stacks and queues • No standard set of operations, but most lists support many typical ones Categories of List Operations • Supporting, such as len, isEmpty, iter, +, == • Index-based (use an index position) • Content-based (use an object) • Position-based (move a cursor) Supporting Operations L.isEmpty() Returns true if empty, false otherwise len(L) Returns the number of items in the list str(L) Returns the string representation of the list iter(L) Items are served up from the first position through the last one L1 == L2 Compares items at consecutive positions L1 + L2 Items from L2 follow the items from L1 Index-Based Operations L.insert(i, item) Opens up a slot in the list at index i and inserts item in this slot L[i] Returns the item at index i L.pop(i) Removes and returns the item at index i (or item at last position if i is omitted) L[i] = item Replaces the item at index i with the item Preconditions on [] and pop: 0 <= i < length of the list Content-Based Operations L.append(item) adds item at the list’s tail (method add has same effect) item in L returns true if the list contains an object equal to item L.index(item) returns the index of the first instance of item in the list L.remove(item) removes the first instance of item from the list Preconditions on index and remove: item must be in the list Position-Based Operations for Navigation LI = L.listIterator() returns a new list iterator object on a list LI.first() moves the cursor to the first item LI.hasNext() returns true if there are any items following the current position LI.next() returns the next item and advances the position LI.last() moves the cursor to the last item LI.hasPrevious() returns true if there are any items preceding the current position LI.previous() returns the previous item and moves the position backward Similar to an extended iterator Position-Based Operations for Mutation LI.insert(newItem) LI.remove() LI.replace(newItem) inserts newItem at the current position removes the last item returned by next or previous replaces the last item returned by next or previous List Applications • • • • object heap storage management documents files implementations of other collections List Implementations – list – ArrayList – LinkedList – ListIterator standard Python (array-based) array-based two-way nodes (allows insertions, removals, movement to previous items) Performance Tradeoffs lyst = ArrayList() # Add some objects to lyst # Traverse the list to print ‘em all for item in lyst: print(item) The simple iterator has the same performance in all list implementations Constant-time access to each item, so loop is no worse than linear Performance Tradeoffs lyst = LinkedList() # Add some objects to lyst # Traverse the list to print ‘em all for item in lyst: print(item) The simple iterator has the same performance in all list implementations Constant-time access to each item, so loop is no worse than linear Performance Tradeoffs lyst = ArrayList() # Add some numbers to lyst # Traverse the list to increment ‘em all for i in range(len(lyst)): lyst[i] += 1 Index-based traversal of a list using [] is needed to replace all items Each [] operation on an array-based list is constant-time, so the loop is no worse than linear Performance Tradeoffs lyst = LinkedList() # Add some numbers to lyst # Traverse the list for i in range(len(lyst)): lyst[i] += 1 Index-based traversal of a LinkedList using [] looks like it would be linear, but it’s actually quadratic! Almost all LinkedList operations are linear, including [] Performance Tradeoffs lyst = LinkedList() # Add some objects to lyst # Traverse the list rator = lyst.listIterator() while rator.hasNext(): print(rator.next()) Can use a list iterator for traversals of a list, in either direction Performance Tradeoffs lyst = LinkedList() # Add some numbers to lyst # Traverse the list to increment ‘em all rator = lyst.listIterator() while rator.hasNext(): number = rator.next() rator.replace(number + 1) Can use a list iterator to traverse a list and replace its items One-Way Linked Structures head 5 4 3 2 A one-way linked structure supports movement in one direction only; cannot move backward Access at the head is O(1), but access anywhere else is O(N) Insertion or removal at the head is a special case Tweak with a Tail Pointer head tail 5 4 3 2 Access to either end is O(1), but generally is still O(N) Still cannot move backward; insertion or removal at the head or tail is still a special case Removal at the tail is still linear Two-Way Linked Structures D1 D2 D3 A circular, doubly linked structure with a dummy header node • permits movement in both directions • allows constant-time access to the head or tail • eliminates special cases in code when access is at the beginning or the end of the structure An Empty Structure When there are no data, there is a single dummy header node Its two links point ahead and back to itself Its data field is None The Node Class class TwoWayNode(object): def __init__(self, data, previous = None, next = None): self.data = data self.previous = previous self.next = next Strictly a utility class No need for accessor or mutator methods Declaring an External Pointer class TwoWayNode(object): def __init__(self, data, previous = None, next = None): self.data = data self.previous = previous self.next = next head = TwoWayNode(None) head.previous = head.next = head head Appending a Node head.previous always points to the last node The last node’s next pointer always points back to head temp = TwoWayNode("A", head.previous, head) temp head “A” Appending a Node head.previous always points to the last node The last node’s next pointer always points back to head temp = TwoWayNode("A", head.previous, head) head.previous.next = temp temp head “A” Appending a Node head.previous always points to the last node The last node’s next pointer always points back to head temp = TwoWayNode("A", head.previous, head) head.previous.next = temp head.previous = temp temp head “A” Analysis No loop is needed to locate the last node Append is a constant time operation! No if statements needed to check for special cases temp = TwoWayNode("A", head.previous, head) head.previous.next = temp head.previous = temp temp head “A” For Monday List Iterators