Lecture 15 Linked Lists & Trees
These are my notes for SICP(Structure and Interpretation of Computer Programs). Hope they’ll be of some help to you.
Linked Lists
- A simple but powerful data structure
- Can be used to implement other data structures, e.g. stack, queues
- Fast insertions/deletions, etc.
Linked list definition
A Linked List either:
- empty
- Composed of a first element and the rest of the linked list
- rest contains a pointer to a linked list
- List terminated with an empty linked list
Linked lists are sequences where each value is the first element of a pair.
Creating linked lists
We’ll define a linked list recursively by making a constructor that takes in a first and rest value.
Link class
class Link:
empty = () #You should not assume the representation here. It could be 'I'm empty'
def __init__(self, first, rest=empty): #Rest defaults to the empty list
assert rest is Link.empty or isinstance(rest, Link)
self.first = first #.first gives elements in the list
self.rest = rest #.rest traverses
Feel free to use environment diagrams to help you understand the structure.
Processing Linked Lists
sum
Goal: Given a linked list, return the sum of all elements in the linked list
def sum(linked_list): #the linked_list here is not nested
if linked_list is Link.empty:
return 0
return linked_list.first + sum(linked_list.rest)
display_link
Goal: Given a linked list, return a string representing the elements in the linked list
def display_link(link):
result = ''
while link is not Link.empty:
if isinstance(link.first, Link):
elem = display_link(link.first) #used to process nested link list
else:
elem = str(link.first)
result += ' ' + elem
link = link.rest
return '<' + result + ' >'
map
Goal: Given a linked list, and a one argument function, return a new linked list obtained from applying the function to each element of the linked list
def map(f, link):
if link is Link.empty:
return Link.empty
return Link(f(link.first), map(f, link.rest))
Mutating Linked Lists
map
Goal: Given a linked list and a one argument function, mutate the linked list by applying f to each element.
def map(lnk, f): #using iteration
"""
>>> lnk = Link(1, Link(2, Link(3)))
>>> map(lnk, lambda x:x * 2)
>>> display_link(lnk)
'<2, 4, 6>'
"""
if lnk is Link.empty:
return
lnk.first = f(lnk.first)
map(lnk.rest, f)
def map(lnk, f): #using iteration
while lnk is not Link.empty:
lnk.first = f(lnk.first)
lnk = lnk.rest #Note that the original lnk will not shrink
Why Linked Lists?
Insert element at index 1
Total number of operations = the length of the list minus 1
inserted_elem = Link(2)
inserted_elem.rest = lnk.rest
lnk.rest = inserted_elem
Tree Class
A Tree is a label and a list of branches; each branch is a Tree
class Tree:
def __init__(self, label, branches=[]):
self.label = label
for branch in branches:
assert isinstance(branch, Tree)
self.branches = branches