Open In App

Split a Circular Linked List into three halves of almost same size

Improve
Improve
Like Article
Like
Save
Share
Report

Split given Circular Linked List into three halves without calculating its length such that the difference between a linked list with a maximum number of nodes and a linked list with a minimum number of nodes is minimum.

Examples:

Input: Circular Linked List: 1->3->5->7->9
Output: 1 3
              5 7
               9

Input: Circular Linked List: 2->4->8
Output: 2 
              4
             8

 

Approach: The approach to solving this problem is using the tortoise and hare algorithm.

  • Move the slow, avg, and fast pointers by 1, 2 and 3
  • When the fast pointer reached NULL, avg pointer reached the end of the second halves and the slow pointer reached the end of the first halves.
  • Make the Third half circular.
  • Make the second half circular.
  • Make the first half circular.
  • Set head pointers of the two linked list

Below is the implementation of the above approach:

C++




// Program to split a circular linked list
// into three halves
#include <bits/stdc++.h>
using namespace std;
 
/* structure for a node */
class Node {
public:
    int data;
    Node* next;
};
 
// Function to split a list
// (starting with head) into three lists.
// head1_ref, head2_ref & head3_ref are
// references to head nodes of the
// three resultant linked lists
void splitList(Node* head, Node** head1_ref,
               Node** head2_ref,
               Node** head3_ref)
{
    Node* slow_ptr = head;
    Node* avg_ptr = head->next;
    Node* fast_ptr = head->next->next;
 
    if (head == NULL
        || head->next == NULL
        || head->next->next == NULL)
        return;
 
    while (fast_ptr->next != head
           && fast_ptr->next->next != head) {
 
        if (fast_ptr->next->next->next
            != head)
            fast_ptr
                = fast_ptr->next->next->next;
        else {
            fast_ptr = fast_ptr->next->next;
        }
        avg_ptr = avg_ptr->next->next;
        slow_ptr = slow_ptr->next;
    }
 
    while (fast_ptr->next != head)
        fast_ptr = fast_ptr->next;
 
    // Make third half circular
    *head3_ref = avg_ptr->next;
    fast_ptr->next = *head3_ref;
 
    // Make second half circular
    *head2_ref = slow_ptr->next;
    avg_ptr->next = *head2_ref;
 
    // Make first half circular
    *head1_ref = head;
    slow_ptr->next = *head1_ref;
}
 
// Function to insert a node at
// the beginning of a Circular linked list
void push(Node** head_ref, int data)
{
    Node* ptr1 = new Node();
    Node* temp = *head_ref;
    ptr1->data = data;
    ptr1->next = *head_ref;
 
    // If linked list is not NULL then
    // set the next of last node
    if (*head_ref != NULL) {
        while (temp->next != *head_ref)
            temp = temp->next;
        temp->next = ptr1;
    }
    else
        // For the first node
        ptr1->next = ptr1;
 
    *head_ref = ptr1;
}
 
// Function to print nodes in
// a given Circular linked list
void printList(Node* head)
{
    Node* temp = head;
    if (head != NULL) {
        do {
            cout << temp->data << " ";
            temp = temp->next;
        } while (temp != head);
    }
    cout << endl;
}
 
// Driver Code
int main()
{
    int list_size, i;
 
    // Initialize lists as empty
    Node* head = NULL;
    Node* head1 = NULL;
    Node* head2 = NULL;
    Node* head3 = NULL;
 
    // Created linked list will be
    // 1->3->5->7->9
    push(&head, 1);
    push(&head, 3);
    push(&head, 5);
    push(&head, 7);
    push(&head, 9);
 
    // Split the list
    splitList(head, &head1, &head2, &head3);
 
    // First Circular Linked List
    printList(head1);
 
    // Second Circular Linked List
    printList(head2);
 
    // Third Circular Linked List
    printList(head3);
 
    return 0;
}


Java




// Program to split a circular linked list
// into three halves
import java.util.*;
class GFG{
 
  /* structure for a node */
  static class Node {
 
    int data;
    Node next;
  };
 
  // Function to split a list
  // (starting with head) into three lists.
  // head1_ref, head2_ref & head3_ref are
  // references to head nodes of the
  // three resultant linked lists
 
  static Node head1_ref;
  static Node head2_ref;
  static Node head3_ref;
  static void splitList(Node head)
  {
    Node slow_ptr = head;
    Node avg_ptr = head.next;
    Node fast_ptr = head.next.next;
 
    if (head == null
        || head.next == null
        || head.next.next == null)
      return;
 
    while (fast_ptr.next != head
           && fast_ptr.next.next != head) {
 
      if (fast_ptr.next.next.next
          != head)
        fast_ptr
        = fast_ptr.next.next.next;
      else {
        fast_ptr = fast_ptr.next.next;
      }
      avg_ptr = avg_ptr.next.next;
      slow_ptr = slow_ptr.next;
    }
 
    while (fast_ptr.next != head)
      fast_ptr = fast_ptr.next;
 
    // Make third half circular
    head3_ref = avg_ptr.next;
    fast_ptr.next = head3_ref;
 
    // Make second half circular
    head2_ref = slow_ptr.next;
    avg_ptr.next = head2_ref;
 
    // Make first half circular
    head1_ref = head;
    slow_ptr.next = head1_ref;
  }
 
  // Function to insert a node at
  // the beginning of a Circular linked list
  static Node push(Node head_ref, int data)
  {
    Node ptr1 = new Node();
    Node temp = head_ref;
    ptr1.data = data;
    ptr1.next = head_ref;
 
    // If linked list is not null then
    // set the next of last node
    if (head_ref != null) {
      while (temp.next != head_ref)
        temp = temp.next;
      temp.next = ptr1;
    }
    else
      // For the first node
      ptr1.next = ptr1;
 
    head_ref = ptr1;
    return head_ref;
  }
 
  // Function to print nodes in
  // a given Circular linked list
  static void printList(Node head)
  {
    Node temp = head;
    if (head != null) {
      do {
        System.out.print(temp.data+ " ");
        temp = temp.next;
      } while (temp != head);
    }
    System.out.println();
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int list_size, i;
 
    // Initialize lists as empty
    Node head = null;
    head1_ref = null;
    head2_ref = null;
    head3_ref = null;
 
    // Created linked list will be
    // 1.3.5.7.9
    head = push(head, 1);
    head = push(head, 3);
    head = push(head, 5);
    head = push(head, 7);
    head = push(head, 9);
 
    // Split the list
    splitList(head);
 
    // First Circular Linked List
    printList(head1_ref);
 
    // Second Circular Linked List
    printList(head2_ref);
 
    // Third Circular Linked List
    printList(head3_ref);
  }
}
 
// This code is contributed by shikhasingrajput


Python3




# Python code for the above approach
 
## Program to split a circular linked list
## into three halves
 
## structure for a node
class Node:
    def __init__(self, d):
        self.data = d
        self.next = None
 
class LinkedList:
 
    def __init__(self):
        self.head = None
     
    ## Function to insert a node at
    ## the beginning of a Circular linked list
    def push(self, data):
        # printList(head_ref)
        ptr1 = Node(data);
        temp = self.head
        ptr1.next = self.head
 
        ## If linked list is not None then
        ## set the next of last node
        if (self.head != None):
            while (temp.next != self.head):
                temp = temp.next;
            temp.next = ptr1
        else:
            ## For the first node
            ptr1.next = ptr1
 
        self.head = ptr1
                 
    ## Function to split a list
    ## (starting with head) into three lists.
    ## head1_ref, head2_ref & head3_ref are
    ## references to head nodes of the
    ## three resultant linked lists
    def splitList(self, llist1, llist2, llist3):
        if (self.head == None or self.head.next == None or self.head.next.next == None):
            return;
         
        slow_ptr = self.head
        avg_ptr = self.head.next
        fast_ptr = self.head.next.next
 
        while (fast_ptr.next != self.head and fast_ptr.next.next != self.head):
 
            if (fast_ptr.next.next.next != self.head):
                fast_ptr = fast_ptr.next.next.next
            else:
                fast_ptr = fast_ptr.next.next
            avg_ptr = avg_ptr.next.next
            slow_ptr = slow_ptr.next
 
        while (fast_ptr.next != self.head):
            fast_ptr = fast_ptr.next
 
        ## Make third half circular
        llist3.head = avg_ptr.next
        fast_ptr.next = llist3.head
 
        ## Make second half circular
        llist2.head = slow_ptr.next
        avg_ptr.next = llist2.head
 
        ## Make first half circular
        llist1.head = self.head
        slow_ptr.next = llist1.head
 
    ## Function to print nodes in
    ## a given Circular linked list
    def printList(self):
        temp = self.head;
        if (temp != None):
            print(temp.data, end=' ')
            temp = temp.next
            while (temp != self.head):
                print(temp.data, end=' ')
                temp = temp.next
        print("")
 
# Driver Code
if __name__=='__main__':
 
    list_size = 0
    i = 0
 
    ## Initialize lists as empty
    llist = LinkedList()
    llist1 = LinkedList()
    llist2 = LinkedList()
    llist3 = LinkedList()
 
    ## Created linked list will be
    ## 1.3.5.7.9
    llist.push(1)
    llist.push(3)
    llist.push(5)
    llist.push(7)
    llist.push(9)
 
    ## Split the list
    llist.splitList(llist1, llist2, llist3)
 
    ## First Circular Linked List
    llist1.printList()
 
    ## Second Circular Linked List
    llist2.printList()
 
    ## Third Circular Linked List
    llist3.printList()
     
     # This code is contributed by subhamgoyal2014.


C#




// C# Program to split a circular linked list
// into three halves
 
using System;
 
public class GFG {
 
    /* structure for a node */
    class Node {
        public int data;
        public Node next;
    }
 
    // Function to split a list
    // (starting with head) into three lists.
    // head1_ref, head2_ref & head3_ref are
    // references to head nodes of the
    // three resultant linked lists
    static Node head1_ref;
    static Node head2_ref;
    static Node head3_ref;
 
    static void splitList(Node head)
    {
        Node slow_ptr = head;
        Node avg_ptr = head.next;
        Node fast_ptr = head.next.next;
 
        if (head == null || head.next == null
            || head.next.next == null)
            return;
 
        while (fast_ptr.next != head
               && fast_ptr.next.next != head) {
            if (fast_ptr.next.next.next != head) {
                fast_ptr = fast_ptr.next.next.next;
            }
            else {
                fast_ptr = fast_ptr.next.next;
            }
            avg_ptr = avg_ptr.next.next;
            slow_ptr = slow_ptr.next;
        }
 
        while (fast_ptr.next != head) {
            fast_ptr = fast_ptr.next;
        }
 
        // Make third half circular
        head3_ref = avg_ptr.next;
        fast_ptr.next = head3_ref;
 
        // Make second half circular
        head2_ref = slow_ptr.next;
        avg_ptr.next = head2_ref;
 
        // Make first half circular
        head1_ref = head;
        slow_ptr.next = head1_ref;
    }
 
    // Function to insert a node at
    // the beginning of a Circular linked list
    static Node push(Node head_ref, int data)
    {
        Node ptr1 = new Node();
        Node temp = head_ref;
        ptr1.data = data;
        ptr1.next = head_ref;
 
        // If linked list is not null then
        // set the next of last node
        if (head_ref != null) {
            while (temp.next != head_ref) {
                temp = temp.next;
            }
            temp.next = ptr1;
        }
        else
            // For the first node
            ptr1.next = ptr1;
 
        head_ref = ptr1;
        return head_ref;
    }
 
    // Function to print nodes in
    // a given Circular linked list
    static void printList(Node head)
    {
        Node temp = head;
        if (head != null) {
            do {
                Console.Write(temp.data + " ");
                temp = temp.next;
            } while (temp != head);
        }
        Console.WriteLine();
    }
 
    static public void Main()
    {
 
        // Code
 
        // Initialize lists as empty
        Node head = null;
        head1_ref = null;
        head2_ref = null;
        head3_ref = null;
 
        // Created linked list will be
        // 1.3.5.7.9
        head = push(head, 1);
        head = push(head, 3);
        head = push(head, 5);
        head = push(head, 7);
        head = push(head, 9);
 
        // Split the list
        splitList(head);
 
        // First Circular Linked List
        printList(head1_ref);
 
        // Second Circular Linked List
        printList(head2_ref);
 
        // Third Circular Linked List
        printList(head3_ref);
    }
}
 
// This code is contributed by lokeshmvs21.


Javascript




<script>
// JavaScript Program to split a circular linked list
// into three halves
 
// Structure for a node
class Node{
    constructor(data){
        this.data = data;
        this.next = null;
    }
}
let head = null;
let head1 = null;
let head2 = null;
let head3 = null;
 
// Function to split a list into three lists.
// head1_ref, head2_ref & head3_ref are
// references to head nodes of the
// three resultant linked lists
function splitList(){
     
    let slow_ptr = head;
    let avg_ptr = head.next;
    let fast_ptr = head.next.next;
     
    if(head == null || head.next == null || head.next.next == null) return;
     
    while(fast_ptr.next != head && fast_ptr.next.next != head){
        if(fast_ptr.next.next.next != head){
            fast_ptr = fast_ptr.next.next.next;
        }else{
            fast_ptr = fast_ptr.next.next;
        }
        avg_ptr = avg_ptr.next.next;
        slow_ptr = slow_ptr.next;
    }
     
    while(fast_ptr.next != head){
        fast_ptr = fast_ptr.next;
    }
         
    // Make third half circular
    head3 = avg_ptr.next;
    fast_ptr.next = head3;
     
    // Make second half circular
    head2 = slow_ptr.next;
    avg_ptr.next = head2;
     
    // Make first half circular
    head1 = head;
    slow_ptr.next = head1;
}
 
// Function to insert a node at
// the beginning of a Circular linked list
function push(data){
    let ptr1 = new Node(data);
    let temp = head;
    ptr1.next = temp;
     
    // If linked list is not NULL then
    // set the next of last node
    if(head != null){
        while(temp.next != head){
            temp = temp.next;
        }
        temp.next = ptr1;
    }else{
        // For the first node
        ptr1.next = ptr1;
    }
    head = ptr1;
}
 
// Function to print nodes in a given circular Linked List
function printList(head){
    document.write("");
    let temp = head;
    if(head != null){
        do{
            document.write(temp.data + " ");
            temp = temp.next;
        }while(temp != head);
    }
}
 
 
// Driver Code
// Created linked list will be 9->7->5->3->1
push(1);
push(3);
push(5);
push(7);
push(9);
 
// Split the list
splitList();
 
// First Circular Linked List
printList(head1);
 
// Second Circular Linked List
printList(head2);
 
// Third Circular Linked List
printList(head3);
// This code is contributed by Yash Agarwal(yashagarwal2852002)
</script>


Output: 

9 7 
5 3 
1

 

Time Complexity: O(N)
Auxiliary Space: O(1)

 



Last Updated : 22 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads