A linked list is a linear data structure where elements are stored in nodes, and each node points to the next node. Unlike arrays, linked lists do not require contiguous memory and can grow or shrink dynamically.
Each node contains two fields: the data and a pointer (or reference) to the next node. The list is accessed through a head pointer that points to the first node.
class Node:
def __init__(self, data):
self.data = data
self.next = None
In a singly linked list, each node has a single pointer to the next node. The last node points to None.
def insert_at_head(head, data):
new_node = Node(data)
new_node.next = head
return new_node
def insert_at_tail(head, data):
if head is None:
return Node(data)
current = head
while current.next:
current = current.next
current.next = Node(data)
return head
def traverse(head):
current = head
while current:
print(current.data, end=" -> ")
current = current.next
print("None")
def search(head, target):
current = head
while current:
if current.data == target:
return True
current = current.next
return False
def delete_node(head, key):
if head is None:
return None
if head.data == key:
return head.next
current = head
while current.next and current.next.data != key:
current = current.next
if current.next:
current.next = current.next.next
return head
def reverse_list(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
Each node has two pointers: prev (to the previous node) and next (to the next node). This allows traversal in both directions and makes deletion at the tail O(1) when a tail pointer is maintained.
class DoublyNode:
def __init__(self, data):
self.data = data
self.prev = None
self.next = None
The last node points back to the head, forming a circle. Useful for round-robin scheduling and applications that cycle through a list repeatedly.
next pointer eventually points back to a previous node). Use Floyd's tortoise-and-hare algorithm (two pointers moving at different speeds).