Linked List
Linked List
• Input: 1->2->3->4->5->6->7->8->NULL, K = 3
• Output: 3->2->1->6->5->4->8->7->NULL
• Input: 1->2->3->4->5->6->7->8->NULL, K = 5
• Output: 5->4->3->2->1->8->7->6->NULL
Algorithm
• reverse(head, k)
• Reverse the first sub-list of size k. While reversing keep track of the next
node and previous node. Let the pointer to the next node be next and
pointer to the previous node be prev. See this post for reversing a
linked list.
• head->next = reverse(next, k) ( Recursively call for rest of the list and
link the two sub-lists )
• Return prev ( prev becomes the new head of the list (see the diagrams
of an iterative method of this post )
Node* reverse(Node* head, int k)
#include <bits/stdc++.h> {
using namespace std; // base case
if (!head)
/* Link list node */ return NULL;
class Node { Node* current = head;
Node* next = NULL;
public:
Node* prev = NULL;
int data; int count = 0;
Node* next;
}; /*reverse first k nodes of the linked list */
while (current != NULL && count < k) {
/* Reverses the linked list in groups next = current->next;
current->next = prev;
of size k and returns the pointer
prev = current;
to the new head node. */ current = next;
count++;
}
/* next is now a pointer to (k+1)th node void push(Node** head_ref, int new_data)
Recursively call for the list starting from {
current. /* allocate node */
And make rest of the list as next of first Node* new_node = new Node();
node */
if (next != NULL) /* put in the data */
head->next = reverse(next, k); new_node->data = new_data;
/* prev is new head of the input list */ /* link the old list off the new node */
return prev; new_node->next = (*head_ref);
}
/* move the head to point to the new node
/* UTILITY FUNCTIONS */ */
/* Function to push a node */ (*head_ref) = new_node;
}
push(&head, 9);
/* Function to print linked list */
push(&head, 8);
void printList(Node* node)
push(&head, 7);
{
push(&head, 6);
while (node != NULL) {
push(&head, 5);
cout << node->data << " ";
push(&head, 4);
node = node->next;
push(&head, 3);
}
push(&head, 2);
}
push(&head, 1);
/* Driver code*/
cout << "Given linked list \n";
int main() printList(head);
{ head = reverse(head, 3);
/* Start with the empty list */
Node* head = NULL; cout << "\nReversed Linked list \n";
printList(head);
/* Created Linked list return (0);
is 1->2->3->4->5->6->7->8->9 */ }
Output
Given linked list
123456789
Complexity Analysis:
Time Complexity: O(n).
Traversal of the list is done only once, and it has ‘n’ elements.
Auxiliary Space: O(n/k).
For each Linked List of size n, n/k or (n/k)+1 calls will be made during the
recursion.
Merge Sort for Linked Lists
• Merge sort is often preferred for sorting a linked list.
1) If the head is NULL or there is only one element in the Linked List
then return.
return 0;
}
QuickSort on Singly Linked List
/* A utility function to insert a node at
#include <cstdio> thebeginning of* linked list */
void push(struct Node** head_ref, int
#include <iostream> new_data)
using namespace std; {
/* allocate node */
struct Node* new_node = new Node;
/* a node of the singly linked
/* put in the data */
list */ new_node->data = new_data;
struct Node {
/* link the old list off the new node */
int data; new_node->next = (*head_ref);
struct Node* next;
/* move the head to point to the new node
}; */
(*head_ref) = new_node;
}
/* A utility function to print linked list */ // Partitions the list taking the last element as
void printList(struct Node* node) the pivot
{ struct Node* partition(struct Node* head,
while (node != NULL) { struct Node* end,
printf("%d ", node->data); struct Node** newHead,
node = node->next; struct Node** newEnd)
} {
printf("\n"); struct Node* pivot = end;
} struct Node *prev = NULL, *cur = head, *tail
= pivot;
// Returns the last node of the list
struct Node* getTail(struct Node* cur) // During partition, both the head and end of
{ the list
while (cur != NULL && cur->next != NULL) // might change which is updated in the
cur = cur->next; newHead and
return cur; // newEnd variables
}
else // If cur node is greater than pivot
while (cur != pivot) {
{
if (cur->data < pivot->data) { // Move cur node to next of tail,
// First node that has a value and change
less than the // tail
// pivot - becomes the new if (prev)
head prev->next = cur->next;
if ((*newHead) == NULL) struct Node* tmp = cur->next;
cur->next = NULL;
(*newHead) = cur;
tail->next = cur;
tail = cur;
prev = cur; cur = tmp;
cur = cur->next; }
} }
// here the sorting happens exclusive of the
// If the pivot data is the smallest element in end node
the struct Node* quickSortRecur(struct Node*
// current list, pivot becomes the head head,
if ((*newHead) == NULL) struct Node* end)
(*newHead) = pivot; {
// base condition
// Update newEnd to the current last node if (!head || head == end)
(*newEnd) = tail; return head;
cout << "Linked List after sorting \n"; Auxiliary Space: O(n)
printList(a);
return 0;
}