A linked list is a data structure where each element, called a node, contains two parts: the actual data and a reference to the next node. This "next" reference links the nodes together, creating a dynamic sequence of elements. A nice analogy for this is imagining a chain with several links. Each link in the chain represents a node in the linked list. The links are connected to each other, forming a sequence.
Let's try to make a linked list using Python. First, let's take a look in building the fundamental part of a linked list - the Node
.
class Node:
def __init__(self,data):
self.data = data
self.next = None
We start by initializing a Node
class, with data and next attributes. It accepts data as a parameter for it to be stored to its self.data
attribute. On the other hand, the self.next
attribute is initially defined as None. We've defined the Node
as if it's an isolated link, not yet chained in a linked list.
Then we proceed with the LinkedList
class:
class LinkedList:
def __init__(self,head=None)
self.head = head
def insert(self, newNode):
if self.head:
current = self.head
while current.next:
current = current.next
current.next = newNode
else:
self.head = newNode
The LinkedList
class is set to manage the linked list. It initializes the head
attribute, which represents the first node of the linked list (hence, the head!). It takes a head
parameter, which has a default value of None
. The reason behind this has something to do with the only method we defined, which is ---.
The insert
method handles the insertion of a new node at the end of the linked list. It takes a newNode
parameter, which is an instance of the Node
class. The rationale for the conditional statements defined there are as follows:
If the linked list is not empty, as proven by checking if there is a head (hence, whether
if self.head
is truthy!), the method traverses the list starting from thehead
node using awhile
loop. Why do we have to traverse the list? Because it is trying to find the last node. As you may recall, we have initiated thenext
attribute for a node. The method would iterate through thenext
attributes until it reaches the node with anext
attribute ofNone
, which is the last node! Then, it sets thenext
reference of the last node to thenewNode
, effectively inserting it at the end of the list.If the linked list is empty, as proven that
self.head
isNone
(simply put, the else logic for not meeting theif self.head
condition above), thenewNode
becomes the first node in the list (hence, the head!), so it is assigned to thehead
attribute. And yes, this is the reason why we set the default value of head asNone
, to handle cases like this.
This is how our code looks like overall:
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkedList:
def __init__(self,head=None)
self.head = head
def insert(self, newNode):
if self.head:
current = self.head
while current.next:
current = current.next
current.next = newNode
else:
self.head = newNode
Now, to see this code in action, we need to add a display
method inside the LinkedList
class:
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkedList:
def __init__(self,head=None)
self.head = head
def insert(self, newNode):
if self.head:
current = self.head
while current.next:
current = current.next
current.next = newNode
else:
self.head = newNode
#added a helper method to display the LinkedList
def display(self):
current = self.head
while current:
print(current.data, end=' ')
current = current.next
print()
We should first create samples of Node
, then create a LinkedList()
. Then we join all the created nodes by accessing the LinkedList()
's insert
method.
# Creating nodes
node1 = Node(10)
node2 = Node(20)
node3 = Node(30)
# Creating a linked list
myList = LinkedList()
# Inserting nodes into the linked list
myList.insert(node1)
myList.insert(node2)
myList.insert(node3)
Finally, we call the display
method:
myList.display()
# Output:
# 10 20 30
We can add more features on the LinkedList class by adding more methods or modifying the insert method. I'll try to demonstate in the future how we can reuse this class to solve linked list related algorithm problems.