Lecture 18 Linked Lists
- Questions
- Lists vs Linked Lists
- List is like a bus
- A linked list is like a train (more flexible and can expand)
- Linked Lists
- Chain of objects where each object holds a value and a reference to the next link
- Linked list ends when the final reference is empty
- Linked Lists Class
- L = Link(1, Link(2, Link(3)))
- Mutating Linked Lists
- Attribute assignments can change first and rest attributes of a Link
- Using assignment statements to mutate a linked list
- There can be infinite lists
- Setting the sublist as the linked list itself
- cyclic linked lists link back on themselves
- Nested Linked Lists
- first can also be a linked list
- Iteration with Linked Lists
- Linked lists are recursive data types and therefore lead to recursive implementations
- Using while loops
- Doing something with the first element: l.first
- Shift the pointer to the next node: l = l.rest
- While condition: l is not Link.empty
- Implementing Functions
def range_link(start, end)
"""
Making a function that returns a link containing consecutive integers from start to end
not including end
similar to how range works
"""
if start == end:
return link.empty
else:
return link(start, range_link(start+1, end))
def map_link(f, ll):
"""
Returning a link that contains f(x) for each x in link ll
"""
if ll.rest is Link.empty:
return link.empty
else:
return link(f(ll.first), map_link(f, ll.rest))
def filter_link(f, ll):
"""
Return a link that contains only the elements x of link ll
for which f(x) is a true value
"""
if ll.rest is Link.empty:
return Link.empty
elif f(ll.first):
return Link(ll.first, filter_link(f, ll.rest))
else:
return filter_link(f, ll.rest)
- Linked Lists Operations
- Insert
- Linked lists require more space but provide faster insertion
- Delete
- No matter which node you want to delete, it takes one step:
- Point the rest of the node before the one to delete the one after
- Access
- I need to iterate through all the previous nodes using .rest
- Comparing Operations
- Lists
- insert: linear
- append: constant, sometimes linear (depends on memory allocated)
- delete: linear
- find: linear
- access: constant
- Linked Lists
- insert: constant
- delete: constant
- find: linear
- access: linear
- Linked List Exercises
def ordered(s, key=lambda x:x)
"""Is link s ordered"""
if s.rest is Link.empty or s is Link.empty:
return True
elif key(s.first) > key(s.rest.first):
return False
else:
ordered(s.rest, key)
def merge(s, t):
"""
Return a sorted Link containing the eleemtns of sorted s & t
"""
if s is Link.empty:
return s
elif t is Link.empty:
return t
elif s.first < t.first:
return Link(s.first, merge(s.rest, t))
else:
return Link(t.first, merge(s, t.rest)
def merge_in_place(s, t);
"""Return sorted Link containing elements of sorted s & t"""
if s is Link.empty:
return s
elif t is Link.empty:
return t
elif s.first < t.first:
s.rest = merge_in_place(s.rest, t)
return s
else:
t.rest = merge_in_place(s, t.rest)
return t
- Circular, Doubly Linked Lists
- Circular linked list → list looping back on itself
- With doubly linked list
- you can get the information about the link before and link after
- it has self.next
- also has self.prev