I am currently taking an online computer science introductory course and have just learned the concept of a linked list. Though I understand the concept of linked lists, I still am unsure as how to deal with linked lists.
As such, I seek out help in solving the following problem, which will be of significant help for my understanding of linked lists:
Write a function (not in LinkedList class definition) that given a linked list, will change that linked list to filter out odd numbers. Immediately after the function returns, the linked list will only have even numbers.
I am unsure as to how to access the nodes in the list and check whether they are odd or even and remove or keep them accordingly.
I apologize if this seems like a trivial question, but I would appreciate any help that might help me learn.
The code for the linked list and node classes (as provided by the online course):
class Node: def __init__(self, data=None, next_node=None): self.data = data self.next = next_node def __str__(self): return str(self.data) class LinkedList: def __init__(self): self.length = 0 self.head = None def print_list(self): node = self.head while node is not None: print(node, end=' ') node = node.next print('') def add_at_head(self, node): node.next = self.head self.head = node self.length += 1 def remove_node_after(self, node): if node.next is not None: temp = node.next node.next = node.next.next temp.next = None self.length -= 1 def remove_first_node(self): if self.head is None: return temp = self.head self.head = self.head.next temp.next = None self.length -= 1 def print_backward(self): def print_nodes_backward(node): if node.next is not None: print_nodes_backward(node.next) if node is not None: print(node, end=' ') if self.head is not None: print_nodes_backward(self.head) print('')
Let's say you have a bare-bones simple linked list that looks like this:
class LinkedList:
class ListNode:
def __init__(self, data):
self.data = data
self.next = None
def __init__(self):
self.head = None
def add(self, data):
if self.head is None:
self.head = LinkedList.ListNode(data)
else:
current_node = self.head
while current_node.next is not None:
current_node = current_node.next
current_node.next = LinkedList.ListNode(data)
def __str__(self):
ret = "["
current_node = self.head
while current_node is not None:
ret = ret + str(current_node.data)
if current_node.next is not None:
ret = ret + ", "
current_node = current_node.next
ret = ret + "]"
return ret
In other words, the LinkedList
contains a single head
, which is a ListNode
. Every element in the Linked List is contained in a ListNode
, and each ListNode
points towards the next element in the list.
As you can see, for adding an element to the list, we either create a node at the head if the list is empty (i.e. self.head is None
), or we traverse to the end of the list by continuously jumping to the .next
element for each ListNode
, starting from the head
. We also use this paradigm for printing a string representation of our list.
So, to remove any node from the linked list, we can simply change the node that references it, so that the node we want to remove gets skipped. At which point it will disappear.
To remove all list nodes containing odd-numbered data, we might do something like this:
def remove_odds(self):
# special case: head node
# remove odd head elements by simply setting head to the next element after
while (self.head is not None) and (self.head.data % 2 == 1):
self.head = self.head.next
# regular case: the rest of the nodes
current_node = self.head
while (current_node is not None) and (current_node.next is not None):
# if the next node's data is odd, then
if current_node.next.data % 2 == 1:
# skip that node by pointing this node's .next to the next node's .next
current_node.next = current_node.next.next
# otherwise, move forwards in the list
else:
current_node = current_node.next
Proof of concept:
>>> lst = LinkedList()
>>> lst.add(2)
>>> lst.add(5)
>>> lst.add(6)
>>> lst.add(3)
>>> lst.add(7)
>>> lst.add(8)
>>> lst.add(10)
>>> lst.add(1)
>>> lst.add(4)
>>> print(lst)
[2, 5, 6, 3, 7, 8, 10, 1, 4]
>>> lst.remove_odds()
>>> print(lst)
[2, 6, 8, 10, 4]