Linked List
Introduction
Linked lists are a data structure that are used to store a sequence of data. They are used to store data in a linear fashion. The data is stored in nodes, which are connected to each other. The first node is called the head and the last node is called the tail. The head and tail are not connected to each other. The head is connected to the first node and the tail is connected to the last node.
Big O
The following is a table of the Big O notation for operations of linked lists and lists.

Under the hood
A node is actually a class that has two properties: value and next. The value is the data that is stored in the node and the next is a reference to the next node. A node can be seen as a dictionary with two keys: value and next. For example,
{
"value": 4,
"next": None
}
You can think about a linked list as a set of nested dictionaries.
Constructor
class Node:
def __init__(self, value):
self.value = value
self.next = None
class LinkedList:
def __init__(self, value):
new_node = Node(value)
self.head = new_node
self.tail = new_node
self.length = 1
my_linked_list = LinkedList(4)
print(my_linked_list.head.value)
Print List
def print_list(self):
temp = self.head
while temp is not None:
print(temp.value)
temp = temp.next
Append
def append(self, value):
new_node = Node(value)
if self.length == 0:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
self.length += 1
return True
Pop
def pop(self):
if self.length == 0:
return None
temp = self.head
pre = self.head
while(temp.next):
pre = temp
temp = temp.next
self.tail = pre
self.tail.next = None
self.length -= 1
if self.length == 0:
self.head = None
self.tail = None
return temp.value
Prepend
def prepend(self, value):
new_node = Node(value)
if self.length == 0:
self.head = new_node
self.tail = new_node
else:
new_node.next = self.head
self.head = new_node
self.length += 1
return True
Pop first
def pop_first(self):
if self.length == 0:
return None
temp = self.head
self.head = self.head.next
temp.next = None
self.length -= 1
if self.length == 0:
self.tail = None
return temp
Get
def get(self, index):
if index < 0 or index >= self.length:
return None
temp = self.head
for _ in range(index):
temp = temp.next
return temp
Set
def set_value(self, index, value):
temp = self.get(index)
if temp:
temp.value = value
return True
return False
Insert
def insert(self, index, value):
if index < 0 or index > self.length:
return False
if index == 0:
return self.prepend(value)
if index == self.length:
return self.append(value)
new_node = Node(value)
temp = self.get(index - 1)
new_node.next = temp.next
temp.next = new_node
self.length += 1
return True
Remove
def remove(self, index):
if index < 0 or index >= self.length:
return None
if index == 0:
return self.pop_first()
if index == self.length - 1:
return self.pop()
pre = self.get(index - 1)
temp = pre.next
pre.next = temp.next
temp.next = None
self.length -= 1
return temp
Reverse
def reverse(self):
temp = self.head
self.head = self.tail
self.tail = temp
after = temp.next
before = None
for _ in range(self.length):
after = temp.next
temp.next = before
before = temp
temp = after
Last updated