Data structure Cheat sheet
Linked List 👻
Linked list vs Arrays 😱
Arrays
Linked Lists
An existing data structure in the programming language
Yes
No
Fixed size in memory
Yes
No
Elements, or nodes, are stored right after each other in memory (contiguously)
Yes
No (pros) 😍
Memory usage is low
(each node only contains data, no links to other nodes)
Yes
No (cons) 🤬
Elements, or nodes, can be accessed directly (random access)
Yes
No (cons) 🤬
Elements, or nodes, can be inserted or deleted in constant time, no shifting operations in memory needed.
No
Yes (pros) 😍
Types 🧐
type name
explaination
Singly linked list
node has only one address to the next node
Doubly linked list
A doubly linked list has nodes with addresses to
both the previous and the next node
Circular singly
linked list
the same as singly but make the last node points to
the Head instead of null
Circular doubly
linked list
the same as doubly but make the prev of Head points
to the last node instead of null
and the next of last node points to the Head instead
of null
Implementation 👨💻
Type
Singly
Doubly
Circular-Singly
Circular-Doubly
Implementation
// Definition of a Node in a singly
linked list
struct Node {
int data;
struct Node* next;
};
// Function to create a new Node
struct Node* newNode(int data) {
struct Node* temp =
(struct
Node*)malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
return temp;
}
struct Node {
// To store the Value or
data.
int data;
// Pointer to point the
Previous Element
Node* prev;
// Pointer to point the
Next Element
Node* next;
};
// Function to create a new
node
struct Node *createNode(int
new_data) {
struct Node *new_node =
(struct Node *)
malloc(sizeof(struct
Node));
new_node->data = new_data;
new_node->next = NULL;
new_node->prev = NULL;
return new_node;
}
Linked Lists Operations🔥
Operation
Traversal
Single ground
Single circular
we only need to connect the last
node back to the first one.
The same as the doubly just link
the prev of head to last node
and the next of last to the head
Operation
Single ground
Single circular
// Function to traverse and print the singly linked list
void traverseList(struct Node* head) {
// Loop that runs until head is NULL
while (head != NULL) {
// Printing data of current node
printf("%d ", head->data);
// Moving to the next node
head = head->next;
}
printf("\n");
}
Searching
int searchKey(struct Node* head, int key) {
// Initialize curr with the head of linked list
struct Node* curr = head;
// Iterate over all the nodes
while (curr != NULL) {
// If the current node's value is equal to key,
// return true
if (curr->data == key)
return 1;
// Move to the next node
curr = curr->next;
}
// If there is no node with value as key, return false
return 0;
}
Insert Head
// Function to insert a new node at the beginning of the
// list
struct Node* insertAtFront(struct Node* head, int new_data)
// Function to insert a node at the beginning
// of the circular linked list
struct Node *insertAtBeginning(struct Node *last, int value)
Operation
Single ground
{
Single circular
{
// Create a new node with the given data
struct Node* new_node = createNode(new_data);
// Make the next of the new node point to the current
// head
new_node->next = head;
// Return the new node as the new head of the list
return new_node;
struct Node *newNode = createNode(value);
// If the list is empty, make the new node point to itself
// and set it as last
if (last == NULL)
{
newNode->next = newNode;
last = newNode;
return newNode;
}
// Insert the new node at the beginning
newNode->next = last->next;
last->next = newNode;
return last;
}
}
Insert Tail
// Given the head of a list and an int, appends
// a new node at the end and returns the head.
struct Node* append(struct Node* head, int new_data) {
// Create a new node
struct Node* new_node = createNode(new_data);
// If the Linked List is empty, make
// the new node as the head and return
if (head == NULL) {
return new_node;
}
// Store the head reference in a temporary variable
struct Node* last = head;
// Traverse till the last node
while (last->next != NULL) {
last = last->next;
}
// Change the next pointer of the last node
// to point to the new node
last->next = new_node;
// Return the head of the list
return head;
}
// Function to insert a node at the end of a circular linked list
struct Node *insertEnd(struct Node *tail, int value)
{
struct Node *newNode = createNode(value);
if (tail == NULL)
{
// If the list is empty, initialize it with the new node
tail = newNode;
newNode->next = newNode;
}
else
{
// Insert new node after the current tail and update the tail pointer
newNode->next = tail->next;
tail->next = newNode;
tail = newNode;
}
return tail;
}
Operation
Single ground
Single circular
Insert between
// Function to insert a Node at the required position
struct Node *insertPos(struct Node *head, int pos, int data) {
// return if invalid input
if (pos < 1)
return head;
// Head will change if pos=1
if (pos == 1) {
struct Node *newNode = createNode(data);
newNode->next = head;
return newNode;
}
struct Node *curr = head;
// Traverse to the node that will be
// present just before the new node
for (int i = 1; i < pos - 1 && curr != NULL; i++) {
curr = curr->next;
}
// if position is greater than
// number of nodes
}
// Function to insert a node at a specific position in a circular linked list
struct Node* insertAtPosition(struct Node *last, int data, int pos) {
if (last == NULL) {
// If the list is empty
if (pos != 1) {
printf("Invalid position!\n");
return last;
}
// Create a new node and make it point to itself
struct Node *newNode = createNode(data);
last = newNode;
last->next = last;
return last;
}
// Create a new node with the given data
struct Node *newNode = createNode(data);
// curr will point to head initially
struct Node *curr = last->next;
if (pos == 1) {
if (curr == NULL)
return head;
// Insert at the beginning
newNode->next = curr;
struct Node *newNode = createNode(data);
// Update the next pointers
last->next = newNode;
return last;
newNode->next = curr->next;
curr->next = newNode;
}
// Traverse the list to find the insertion point
return head;
for (int i = 1; i < pos - 1; ++i) {
curr = curr->next;
// If position is out of bounds
if (curr == last->next) {
printf("Invalid position!\n");
return last;
}
}
// Insert the new node at the desired position
newNode->next = curr->next;
curr->next = newNode;
// Update last if the new node is inserted at the end
if (curr == last) last = newNode;
Operation
Single ground
Single circular
return last;
}
Delete Head
// Delete the head node and return the new head
struct Node* deleteFirstNode(struct Node* last) {
struct Node* deleteHead(struct Node* head) {
// Check if the list is empty
if (last == NULL) {
// If the list is empty
if (head == NULL)
return NULL;
printf("List is empty\n");
return NULL;
// Store the current head in a
// temporary variable
}
struct Node* head = last->next;
struct Node* temp = head;
// Move the head pointer to the next node
if (head == last) {
// If there is only one node in the list
head = head->next;
// Free the memory of the old head node
free(head);
last = NULL;
free(temp);
return head;
} else {
// More than one node in the list
}
last->next = head->next;
free(head);
}
return last;
}
Delete Tail
// Function to remove the last node of the linked list
struct Node* removeLastNode(struct Node* head)
{
// If the list is empty, return NULL
if (head == NULL) {
return NULL;
// Function to delete the last node in the circular linked list
struct Node* deleteLastNode(struct Node* last) {
if (last == NULL) {
// If the list is empty
printf("List is empty, nothing to delete.\n");
return NULL;
}
// If the list has only one node, delete it and return
}
struct Node* head = last->next;
// NULL
if (head->next == NULL) {
// If there is only one node in the list
if (head == last) {
Operation
Single ground
Single circular
free(head);
return NULL;
free(last);
last = NULL;
}
// Find the second last node
return last;
}
struct Node* second_last = head;
while (second_last->next->next != NULL) {
// Traverse the list to find the second last node
struct Node* curr = head;
second_last = second_last->next;
}
while (curr->next != last) {
curr = curr->next;
// Delete the last node
free(second_last->next);
}
// Update the second last node's next pointer to point to head
// Change next of second last
second_last->next = NULL;
curr->next = head;
free(last);
return head;
last = curr;
return last;
}
}
Delete between
// Function to delete a node at a given position
struct Node* deleteNode(struct Node* head, int position)
struct Node* deleteSpecificNode(struct Node* last, int pos) {
if (last == NULL) {
{
// If the list is empty
printf("List is empty, nothing to delete.\n");
struct Node* temp = head;
struct Node* prev = NULL;
// Base case if linked list is empty
return NULL;
}
if (temp == NULL)
return head;
struct Node* curr = last->next;
struct Node* prev = last;
// Case 1: Head is to be deleted
if (position == 1) {
// If the node to be deleted is the only node in the list
if (curr == last) {
head = temp->next;
free(temp);
free(curr);
last = NULL;
return head;
return last;
}
}
// Case 2: Node to be deleted is in middle
// Traverse till given position
// Traverse the list to find the node to be deleted
for (int i = 1; curr != NULL && i < pos; i++){
for (int i = 1; temp != NULL && i < position; i++) {
prev = temp;
temp = temp->next;
// If given position is found, delete node
prev = curr;
curr = curr->next;
}
prev->next = curr->next;
Operation
Single ground
Single circular
if (temp != NULL) {
prev->next = temp->next;
if (curr == last) {
last = prev;
free(temp);
}
free(curr);
}
else {
printf("Data not present\n");
return last;
}
}
return head;
}
Operation
double ground
Traversal
// Function to traverse the doubly linked list
// in forward direction
void forwardTraversal(struct Node* head) {
struct Node* curr = head;
while (curr != NULL) {
printf("%d ", curr->data);
curr = curr->next;
}
printf("\n");
}
Searching
Insert at start
// Function to insert a new node at the front of doubly linked list
double circular
Operation
double ground
struct Node *insertAtFront(struct Node *head, int new_data) {
// Create a new node
struct Node *new_node = createNode(new_data);
// Make next of new node as head
new_node->next = head;
// Change prev of head node to new node
if (head != NULL) {
head->prev = new_node;
}
// Return the new node as the head of the doubly linked list
return new_node;
}
Insert at end
// Function to insert a new node at the end of the doubly linked list
struct Node* insertEnd(struct Node *head, int new_data) {
struct Node *new_node = createNode(new_data);
// If the linked list is empty, set the new node as the head
if (head == NULL) {
head = new_node;
} else {
struct Node *curr = head;
while (curr->next != NULL) {
curr = curr->next;
}
// Set the next of last node to new node
curr->next = new_node;
// Set prev of new node to last node
new_node->prev = curr;
}
return head;
}
Insert between
double circular
Operation
double ground
// Function to insert a new node at a given position
struct Node* insertAtPosition(struct Node *head, int pos, int new_data) {
// Create a new node
struct Node *new_node = createNode(new_data);
// Insertion at the beginning
if (pos == 1) {
new_node->next = head;
// If the linked list is not empty, set the prev of head to new node
if (head != NULL) {
head->prev = new_node;
}
// Set the new node as the head of linked list
head = new_node;
return head;
}
struct Node *curr = head;
// Traverse the list to find the node before the insertion point
for (int i = 1; i < pos - 1 && curr != NULL; ++i) {
curr = curr->next;
}
// If the position is out of bounds
if (curr == NULL) {
printf("Position is out of bounds.\n");
free(new_node);
return head;
}
// Set the prev of new node to curr
new_node->prev = curr;
// Set the next of new node to next of curr
new_node->next = curr->next;
// Update the next of current node to new node
curr->next = new_node;
// If the new node is not the last node, update the prev of next node to new node
if (new_node->next != NULL) {
new_node->next->prev = new_node;
}
// Return the head of the doubly linked list
return head;
}
double circular
Operation
double ground
Delete start
// Delete the head node and return the new head
struct Node* deleteHead(struct Node* head) {
// Check if the list is empty
if (head == NULL)
return NULL;
// Store the current head in a
// temporary variable
struct Node* temp = head;
// Move the head pointer to the next node
head = head->next;
// Free the memory of the old head node
free(temp);
return head;
}
Delete end
// Function to delete the last node of the doubly linked list
struct Node* delLast(struct Node *head) {
// Corner cases
if (head == NULL)
return NULL;
if (head->next == NULL) {
free(head);
return NULL;
}
// Traverse to the last node
struct Node *curr = head;
while (curr->next != NULL)
curr = curr->next;
// Update the previous node's next pointer
curr->prev->next = NULL;
// Delete the last node
free(curr);
// Return the updated head
return head;
}
double circular
Operation
double ground
Delete between
// Function to delete a node at a specific position
// in the doubly linked list
struct Node* delPos(struct Node* head, int pos) {
// If the list is empty
if (head == NULL)
return head;
struct Node* curr = head;
// Traverse to the node at the given position
for (int i = 1; curr != NULL && i < pos; ++i) {
curr = curr->next;
}
// If the position is out of range
if (curr == NULL)
return head;
// Update the previous node's next pointer
if (curr->prev != NULL)
curr->prev->next = curr->next;
// Update the next node's prev pointer
if (curr->next != NULL)
curr->next->prev = curr->prev;
// If the node to be deleted is the head node
if (head == curr)
head = curr->next;
// Deallocate memory for the deleted node
free(curr);
return head;
}
Useful links and important problems
double circular
reverse single linked list
reverse double linked list
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )