Linked Lists




Pay Notebook Creator: Elaine Chan0
Set Container: Numerical CPU with TINY Memory for 10 Minutes 0
Total0
In [1]:
#crosscompute
In [2]:
# list
class LinkedList:
    def __init__(self):
        self.head = None

    def search(self, x):
        current = self.head # initialize current to head
        while current != None: # loop until current not equal to None
            if current.data == x:
                return True # data found
            current = current.next 
        return False # data not found
    def print_list(self):
        node = self.head
        while node:
            print(node.data)
            node = node.next
            
    def print_nodes(self):
        node = self.head
        while node:
            print(node)
            node = node.next

class Node:
    def __init__(self, data=0, next=None):
        self.data = data
        self.next = next
        
    def insert_after(self, new_node):
        new_node.next = self.next # set current `next` as new node's `next
        self.next = new_node # set new node as current's `next`
        
    # delete node after current, assuming node is not a tail.
    def delete_after(self):
        self.next = self.next.next
In [3]:
# start two empty lists
L1 = LinkedList()
L2 = LinkedList()
In [4]:
# create nodes
L1.head = Node(2)
L1.second = Node(5)
L1.third = Node(7)

L2.head = Node(3)
L2.second = Node(11)
In [5]:
# link the nodes
L1.head.next = L1.second
L1.second.next = L1.third

L2.head.next = L2.second
In [6]:
import gc
list_of_nodes = [obj for obj in gc.get_objects() if isinstance(obj, Node)]; list_of_nodes
Out[6]:
[<__main__.Node at 0x7fc7404db4e0>,
 <__main__.Node at 0x7fc7404dbd30>,
 <__main__.Node at 0x7fc7471c7128>,
 <__main__.Node at 0x7fc7471c70b8>,
 <__main__.Node at 0x7fc7471c7390>]
In [7]:
list_of_lists = [obj for obj in gc.get_objects() if isinstance(obj, LinkedList)]; list_of_lists
Out[7]:
[<__main__.LinkedList at 0x7fc73c126d30>,
 <__main__.LinkedList at 0x7fc73c126da0>]
In [8]:
L1.print_list()
2
5
7
In [9]:
L2.print_list()
3
11
In [10]:
# merge two sorted singly linked lists so that the merged list is still sorted

# naive approach: traverse each list
# grab the min and link to first list
def merge_lists(L1, L2):
    dummy_head = tail = Node(...)
    node1 = L1.head
    node2 = L2.head
    while node1 and node2: # lists not empty
        if node1.data <= node2.data:
            tail.next = node1 # attach node1 to tail of new list
            node1 = node1.next # stepping node1 pointer to the next node on L1
        else:
            tail.next = node2
            node2 = node2.next
        tail = tail.next
    tail.next = node1 or node2 # takes the leftover : take tail of one of the lists and link to new list
    result = LinkedList()
    result.head = dummy_head.next
    return result
In [11]:
L3 = merge_lists(L1, L2)
In [12]:
L3.print_list()
2
3
5
7
11
In [13]:
L1.print_list()
2
3
5
7
11
In [14]:
L2.print_list()
3
5
7
11
In [15]:
list_of_nodes # unchanged
Out[15]:
[<__main__.Node at 0x7fc7404db4e0>,
 <__main__.Node at 0x7fc7404dbd30>,
 <__main__.Node at 0x7fc7471c7128>,
 <__main__.Node at 0x7fc7471c70b8>,
 <__main__.Node at 0x7fc7471c7390>]
In [16]:
list_of_lists 

# ??? Shoud be 3 lists (L1, L2, L3) but only 2
Out[16]:
[<__main__.LinkedList at 0x7fc73c126d30>,
 <__main__.LinkedList at 0x7fc73c126da0>]
In [18]:
L1.print_nodes()
<__main__.Node object at 0x7fc7404db4e0>
<__main__.Node object at 0x7fc7471c70b8>
<__main__.Node object at 0x7fc7404dbd30>
<__main__.Node object at 0x7fc7471c7128>
<__main__.Node object at 0x7fc7471c7390>
In [20]:
L2.print_nodes()
<__main__.Node object at 0x7fc7471c70b8>
<__main__.Node object at 0x7fc7404dbd30>
<__main__.Node object at 0x7fc7471c7128>
<__main__.Node object at 0x7fc7471c7390>
In [21]:
L3.print_nodes()
<__main__.Node object at 0x7fc7404db4e0>
<__main__.Node object at 0x7fc7471c70b8>
<__main__.Node object at 0x7fc7404dbd30>
<__main__.Node object at 0x7fc7471c7128>
<__main__.Node object at 0x7fc7471c7390>
In [ ]: