Open In App

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

Last Updated : 22 Feb, 2023
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)

 



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

Similar Reads