Open In App

Concatenation of two Linked lists in O(1) time

Last Updated : 27 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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

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();


Output

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.


Output

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:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads