Concatenation of two Linked lists in O(1) time
What is a Linked List?
A linked list is a linear data structure, in which the elements are not stored at contiguous memory locations. The elements in a linked list are linked using pointers as shown in the below image:

Example of Linked List
Singly Linked List:
- In, a singly linked list, each node has a value and a pointer to the next node.
- It is of most common linked list.
- We can go only in one direction, head to tail.
Doubly Linked List:
- A Doubly Linked List (DLL) contains an extra pointer, typically called the previous pointer, together with the next pointer and data.
- We can go in both directions, head to tail and tail to head.
Circularly Linked List:
- The circular linked list is a linked list where all nodes are connected to form a circle.
- In a circular linked list, the first node and the last node are connected to each other which forms a circle.
- There is no NULL at the end.
How to Concatenate two linked lists in O(1) time?
There are two cases arise in this case, one for singly or doubly LL and another for circular LL.
1. For Singly and Doubly Linked List:
Concatenation of two lists in O(1) time using either a single linked list or a doubly linked list, provided that you have a pointer to the last node in at least one of the lists. (And, of course, pointers to the list heads.)
Let’s see in the case of Singly LL but in doubly also it works the same way.
C++
// C++ program to concat two singly // linked lists in O(1) time #include <iostream> using namespace std; class Node { public : int data; Node* next; // Constructor Node( int data) { this ->data = data; this ->next = NULL; } // Destructor ~Node() { int value = this ->data; // Memory free if ( this ->next != NULL) { delete next; this ->next = NULL; } } }; void insertAtTail(Node*& tail, int d) { // New node create Node* temp = new Node(d); tail->next = temp; tail = temp; } void print(Node*& head) { Node* temp = head; while (temp != NULL) { cout << temp->data << " " ; temp = temp->next; } cout << endl; } // Function to concatenate two LL in O(1) void concat(Node*& head1, Node*& head2, Node*& tail) { tail->next = head2; } // Driver Code int main() { // Created a new node of First singly LL Node* node1 = new Node(1); // Head pointed to node1 Node* head1 = node1; Node* tail1 = node1; insertAtTail(tail1, 2); insertAtTail(tail1, 3); insertAtTail(tail1, 4); insertAtTail(tail1, 5); cout << "First Linked List: " << endl; print(head1); // Created a new node of Second singly LL Node* node2 = new Node(6); // Head pointed to node1 Node* head2 = node2; Node* tail2 = node2; insertAtTail(tail2, 7); insertAtTail(tail2, 8); insertAtTail(tail2, 9); insertAtTail(tail2, 10); cout << "Second Linked List: " << endl; print(head2); // Concatenate Second LL in First LL concat(head1, head2, tail1); cout << "First Linked List after concatenation: " << endl; // Printing updated head1 print(head1); return 0; } |
Java
// Java program to concat two singly // linked lists in O(1) time import java.io.*; class Node { int data; Node next; // Constructor public Node( int data) { this .data = data; this .next = null ; } } class GFG { public static Node insertAtTail(Node head1, Node tail1, int data) { Node temp = new Node(data); tail1.next = temp; tail1 = temp; return tail1; } public static void print(Node head) { Node temp = head; while (temp != null ) { System.out.print(temp.data + " " ); temp = temp.next; } System.out.println(); } public static void concat(Node head1, Node head2, Node tail1) { tail1.next = head2; } public static void main(String[] args) { Node node1 = new Node( 1 ); Node head1 = node1; Node tail1 = node1; tail1 = insertAtTail(head1, tail1, 2 ); tail1 = insertAtTail(head1, tail1, 3 ); tail1 = insertAtTail(head1, tail1, 4 ); tail1 = insertAtTail(head1, tail1, 5 ); System.out.println( "First Linked List: " ); print(head1); Node node2 = new Node( 6 ); Node head2 = node2; Node tail2 = node2; tail2 = insertAtTail(head2, tail2, 7 ); tail2 = insertAtTail(head2, tail2, 8 ); tail2 = insertAtTail(head2, tail2, 9 ); tail2 = insertAtTail(head2, tail2, 10 ); System.out.println( "Second Linked List: " ); print(head2); concat(head1, head2, tail1); System.out.println( "First Linked List after concatenation: " ); print(head1); } } // This code is contributed by lokesh. |
C#
// C# program to concat two singly // linked lists in O(1) time using System; public class Node { public int data; public Node next; // Constructor public Node( int data) { this .data = data; this .next = null ; } } public class GFG { public static Node insertAtTail(Node head1, Node tail1, int data) { Node temp = new Node(data); tail1.next = temp; tail1 = temp; return tail1; } public static void print(Node head) { Node temp = head; while (temp != null ) { Console.Write(temp.data + " " ); temp = temp.next; } Console.WriteLine(); } public static void concat(Node head1, Node head2, Node tail1) { tail1.next = head2; } static public void Main() { // Code Node node1 = new Node(1); Node head1 = node1; Node tail1 = node1; tail1 = insertAtTail(head1, tail1, 2); tail1 = insertAtTail(head1, tail1, 3); tail1 = insertAtTail(head1, tail1, 4); tail1 = insertAtTail(head1, tail1, 5); Console.WriteLine( "First Linked List: " ); print(head1); Node node2 = new Node(6); Node head2 = node2; Node tail2 = node2; tail2 = insertAtTail(head2, tail2, 7); tail2 = insertAtTail(head2, tail2, 8); tail2 = insertAtTail(head2, tail2, 9); tail2 = insertAtTail(head2, tail2, 10); Console.WriteLine( "Second Linked List: " ); print(head2); concat(head1, head2, tail1); Console.WriteLine( "First Linked List after concatenation: " ); print(head1); } } // This code is contributed by lokeshmvs21. |
Python3
class Node: def __init__( self , data): self .data = data self . next = None def insert_at_tail(tail, d): temp = Node(d) tail. next = temp tail = temp def print_linked_list(head): temp = head while temp: print (temp.data, end = " " ) temp = temp. next print () def concat(head1, head2, tail): tail. next = head2 # Driver Code if __name__ = = "__main__" : # Created a new node of First singly LL node1 = Node( 1 ) # Head pointed to node1 head1 = node1 tail1 = node1 insert_at_tail(tail1, 2 ) insert_at_tail(tail1, 3 ) insert_at_tail(tail1, 4 ) insert_at_tail(tail1, 5 ) print ( "First Linked List: " ) print_linked_list(head1) # Created a new node of Second singly LL node2 = Node( 6 ) # Head pointed to node1 head2 = node2 tail2 = node2 insert_at_tail(tail2, 7 ) insert_at_tail(tail2, 8 ) insert_at_tail(tail2, 9 ) insert_at_tail(tail2, 10 ) print ( "Second Linked List: " ) print_linked_list(head2) concat(head1, head2, tail1) print ( "First Linked List after concatenation: " ) print_linked_list(head1) #code by ksam24000 |
Javascript
// JavaScript program to concatenate two singly linked lists in O(1) time // Define a Node class to represent a node in the linked list class Node { constructor(data) { this .data = data; this .next = null ; } } // Define a function to insert a new node at the end of the linked list function insertAtTail(head1, tail1, data) { // Create a new node with the given data const temp = new Node(data); // Make the current tail node point to the new node tail1.next = temp; // Update the tail pointer to the new node tail1 = temp; // Return the updated tail pointer return tail1; } // Define a function to print the elements of the linked list function print(head) { // Start from the head node let temp = head; // Traverse the linked list until the end is reached let ans = "" ; while (temp !== null ) { ans= ans + temp.data + " " ; temp = temp.next; } console.log(ans); } // Define a function to concatenate two linked lists function concat(head1, head2, tail1) { // Make the next pointer of the tail node of the first linked list point to the head node of the second linked list tail1.next = head2; } // Define the main function to create two linked lists, concatenate them, and print the results function main() { // Create the first linked list const node1 = new Node(1); let head1 = node1; let tail1 = node1; tail1 = insertAtTail(head1, tail1, 2); tail1 = insertAtTail(head1, tail1, 3); tail1 = insertAtTail(head1, tail1, 4); tail1 = insertAtTail(head1, tail1, 5); // Print the first linked list console.log( "First Linked List: " ); print(head1); // Create the second linked list const node2 = new Node(6); let head2 = node2; let tail2 = node2; tail2 = insertAtTail(head2, tail2, 7); tail2 = insertAtTail(head2, tail2, 8); tail2 = insertAtTail(head2, tail2, 9); tail2 = insertAtTail(head2, tail2, 10); // Print the second linked list console.log( "Second Linked List: " ); print(head2); // Concatenate the two linked lists concat(head1, head2, tail1); // Print the first linked list after concatenation console.log( "First Linked List after concatenation: " ); print(head1); } // Call the main function to execute the program main(); |
First Linked List: 1 2 3 4 5 Second Linked List: 6 7 8 9 10 First Linked List after concatenation: 1 2 3 4 5 6 7 8 9 10
Time Complexity: O(1)
Auxiliary Space: O(1)
2. For Circular Linked List:
With a circularly linked list, you can easily concatenate them in O(1) time. It’s just a matter of breaking a link in both lists, and then hooking them together. This assumes, of course, that the order of items isn’t especially important.
Implementation of the concatenation of two Circular linked lists:
C++
// C++ program to concat two // circular linked lists in // O(1) time #include <bits/stdc++.h> using namespace std; // Circular Linked list Node Class class Node { public : int data; Node* next; // Constructor function Node( int data) { this ->data = data; this ->next = NULL; } }; // Function to insert a node in // tail in circular linked list void insertNode(Node*& head, Node*& tail, int d) { // First insertion in circular // linked list if (head == NULL) { Node* newNode = new Node(d); head = newNode; tail = newNode; newNode->next = newNode; } else { // Non-empty list Node* temp = new Node(d); temp->next = tail->next; tail->next = temp; tail = tail->next; } } // Function to print circular linked list void print(Node* head) { Node* curr = head; // If circular linked list is empty if (head == NULL) { cout << "List is Empty " << endl; return ; } // Else iterate until node is NOT head do { cout << curr->data << " " ; curr = curr->next; } while (curr != head); cout << endl; } // Function to concatenate two circularly // LL in O(1) time void concat(Node*& head1, Node*& head2) { Node* temp = head1->next; head1->next = head2->next; head2->next = temp; } // Driver Code int main() { Node* head1 = NULL; Node* tail1 = NULL; insertNode(head1, tail1, 1); insertNode(head1, tail1, 2); insertNode(head1, tail1, 3); insertNode(head1, tail1, 4); insertNode(head1, tail1, 5); Node* head2 = NULL; Node* tail2 = NULL; insertNode(head2, tail2, 6); insertNode(head2, tail2, 7); insertNode(head2, tail2, 8); insertNode(head2, tail2, 9); insertNode(head2, tail2, 10); cout << "Before Concatenation, First circular linked " "list: " ; print(head1); cout << "Before Concatenation, Second circular linked " "list: " ; print(head2); // Concatenate two circular LL concat(head1, head2); cout << "After Concatenation, First circular linked " "list: " ; print(head1); cout << "After Concatenation, Second circular linked " "list: " ; print(head2); return 0; } |
Java
// Java program to concat two // circular linked lists in // O(1) time import java.util.*; // Circular Linked list Node Class class Node { public int data; public Node next; // Constructor function public Node( int data) { this .data = data; this .next = null ; } } // Class for Circular Linked List class CircularLinkedList { public Node head, tail; // Function to insert a node in // tail in circular linked list public void insertNode( int d) { // First insertion in circular // linked list if (head == null ) { Node newNode = new Node(d); head = newNode; tail = newNode; newNode.next = newNode; } else { // Non-empty list Node temp = new Node(d); temp.next = tail.next; tail.next = temp; tail = tail.next; } } // Function to print circular linked list public void print() { Node curr = head; // If circular linked list is empty if (head == null ) { System.out.println( "List is Empty " ); return ; } // Else iterate until node is NOT head do { System.out.print(curr.data + " " ); curr = curr.next; } while (curr != head); System.out.println(); } // Function to concatenate two circularly // LL in O(1) time public void concat(CircularLinkedList cl2) { Node temp = head.next; head.next = cl2.head.next; cl2.head.next = temp; } } // Driver Code public class Main { public static void main(String[] args) { CircularLinkedList cl1 = new CircularLinkedList(); cl1.insertNode( 1 ); cl1.insertNode( 2 ); cl1.insertNode( 3 ); cl1.insertNode( 4 ); cl1.insertNode( 5 ); CircularLinkedList cl2 = new CircularLinkedList(); cl2.insertNode( 6 ); cl2.insertNode( 7 ); cl2.insertNode( 8 ); cl2.insertNode( 9 ); cl2.insertNode( 10 ); System.out.print( "Before Concatenation, First circular linked list: " ); cl1.print(); System.out.print( "Before Concatenation, Second circular linked list: " ); cl2.print(); // Concatenate two circular LL cl1.concat(cl2); System.out.print( "After Concatenation, First circular linked list: " ); cl1.print(); System.out.print( "After Concatenation, Second circular linked list: " ); cl2.print(); } } |
Python3
# Python program to concat two # circular linked lists in # O(1) time # Circular Linked list Node Class class Node: def __init__( self , data): self .data = data self . next = None # Function to insert a node in # tail in circular linked list def insertNode(head, tail, d): # First insertion in circular # linked list if head is None : newNode = Node(d) head = newNode tail = newNode newNode. next = newNode else : # Non-empty list temp = Node(d) temp. next = tail. next tail. next = temp tail = tail. next return head, tail # Function to print circular linked list def printList(head): curr = head # If circular linked list is empty if head is None : print ( "List is Empty" ) return # Else iterate until node is NOT head while curr. next ! = head: print (curr.data, end = ' ' ) curr = curr. next print (curr.data) # Function to concatenate two circularly # LL in O(1) time def concat(head1, head2): temp = head1. next head1. next = head2. next head2. next = temp # Driver Code if __name__ = = '__main__' : head1 = None tail1 = None head1, tail1 = insertNode(head1, tail1, 1 ) head1, tail1 = insertNode(head1, tail1, 2 ) head1, tail1 = insertNode(head1, tail1, 3 ) head1, tail1 = insertNode(head1, tail1, 4 ) head1, tail1 = insertNode(head1, tail1, 5 ) head2 = None tail2 = None head2, tail2 = insertNode(head2, tail2, 6 ) head2, tail2 = insertNode(head2, tail2, 7 ) head2, tail2 = insertNode(head2, tail2, 8 ) head2, tail2 = insertNode(head2, tail2, 9 ) head2, tail2 = insertNode(head2, tail2, 10 ) print ( "Before Concatenation, First circular linked list: " ) printList(head1) print ( "Before Concatenation, Second circular linked list: " ) printList(head2) # Concatenate two circular LL concat(head1, head2) print ( "After Concatenation, First circular linked list: " ) printList(head1) print ( "After Concatenation, Second circular linked list: " ) printList(head2) #code by ksam24000 |
C#
// C# program to concat two // circular linked lists in // O(1) time using System; // Circular Linked list Node Class class Node { public int data; public Node next; public Node( int data) { this .data = data; this .next = null ; } } class Program { // Function to insert a node in // tail in circular linked list static void insertNode( ref Node head, ref Node tail, int d) { // First insertion in circular // linked list if (head == null ) { Node newNode = new Node(d); head = newNode; tail = newNode; newNode.next = newNode; } else { // Non-empty list Node temp = new Node(d); temp.next = tail.next; tail.next = temp; tail = tail.next; } } // Function to print circular linked list static void print(Node head) { Node curr = head; // If circular linked list is empty if (head == null ) { Console.WriteLine( "List is Empty" ); return ; } // Else iterate until node is NOT head do { Console.Write(curr.data + " " ); curr = curr.next; } while (curr != head); Console.WriteLine(); } // Function to concatenate two circularly // LL in O(1) time static void concat( ref Node head1, ref Node head2) { Node temp = head1.next; head1.next = head2.next; head2.next = temp; } // Driver Code static void Main( string [] args) { Node head1 = null ; Node tail1 = null ; insertNode( ref head1, ref tail1, 1); insertNode( ref head1, ref tail1, 2); insertNode( ref head1, ref tail1, 3); insertNode( ref head1, ref tail1, 4); insertNode( ref head1, ref tail1, 5); Node head2 = null ; Node tail2 = null ; insertNode( ref head2, ref tail2, 6); insertNode( ref head2, ref tail2, 7); insertNode( ref head2, ref tail2, 8); insertNode( ref head2, ref tail2, 9); insertNode( ref head2, ref tail2, 10); Console.WriteLine( "Before Concatenation, First circular linked list: " ); print(head1); Console.WriteLine( "Before Concatenation, Second circular linked list: " ); print(head2); concat( ref head1, ref head2); Console.WriteLine( "After Concatenation, First circular linked list: " ); print(head1); Console.WriteLine( "After Concatenation, Second circular linked list: " ); print(head2); Console.ReadKey(); } } |
Javascript
// javascript program to concat two // circular linked lists in // O(1) time // Circular Linked list Node Class class Node { // Constructor function constructor(data) { this .data = data; this .next = null ; } } // Function to insert a node in // tail in circular linked list function insertNode(head, tail, d) { // First insertion in circular // linked list if (head == null ) { let newNode = new Node(d); head = newNode; tail = newNode; newNode.next = newNode; } else { // Non-empty list let temp = new Node(d); temp.next = tail.next; tail.next = temp; tail = tail.next; } return [head, tail]; } // Function to print circular linked list function print(head) { let curr = head; // If circular linked list is empty if (head == null ) { console.log( "List is Empty " ); return ; } // Else iterate until node is NOT head do { console.log(curr.data + " " ); curr = curr.next; } while (curr != head); console.log( "\n" ); } // Function to concatenate two circularly // LL in O(1) time function concat(head1, head2) { let temp = head1.next; head1.next = head2.next; head2.next = temp; } // Driver Code let head1 = null ; let tail1 = null ; [head1, tail1] = insertNode(head1, tail1, 1); [head1, tail1] = insertNode(head1, tail1, 2); [head1, tail1] = insertNode(head1, tail1, 3); [head1, tail1] = insertNode(head1, tail1, 4); [head1, tail1] = insertNode(head1, tail1, 5); let head2 = null ; let tail2 = null ; [head2, tail2] = insertNode(head2, tail2, 6); [head2, tail2] = insertNode(head2, tail2, 7); [head2, tail2] = insertNode(head2, tail2, 8); [head2, tail2] = insertNode(head2, tail2, 9); [head2, tail2] = insertNode(head2, tail2, 10); console.log( "Before Concatenation, First circular linked list: " ); print(head1); console.log( "Before Concatenation, Second circular linked list: " ); print(head2); // Concatenate two circular LL concat(head1, head2); console.log( "After Concatenation, First circular linked list: " ); print(head1); console.log( "After Concatenation, Second circular linked list: " ); print(head2); // the code is contributed by Nidhi goel. |
Before Concatenation, First circular linked list: 1 2 3 4 5 Before Concatenation, Second circular linked list: 6 7 8 9 10 After Concatenation, First circular linked list: 1 7 8 9 10 6 2 3 4 5 After Concatenation, Second circular linked list: 6 2 3 4 5 1 7 8 9 10
Time Complexity: O(1)
Auxiliary Space: O(1)
Related Articles:
Please Login to comment...