Segregate even and odd nodes in a Linked List

Problem Statement

In this problem, we are given a LinkedList with even and odd valued nodes and are asked to segregate these nodes. Note that we also have to maintain the order in which the nodes were in the original linked list.

Input Linked List:

Output Linked List:

Problem Statement Understanding

Let's try to understand the problem with help of an example:

By the way the statement Segregate even and odd nodes indicates that we need to rearrange the nodes of the linked list in such a way that all the even valued nodes appears before odd valued nodes in the modified linked list, and we also have to maintain the order in which the nodes were in the original linked list.

If our linked list is 1β†’2β†’3.

Then, while segregating the even and odd nodes of the linked list:

  • The node 2 is even valued, so it will come in front, maintaining its order in the original linked list, forming 2.
  • The nodes 1 and 3 are odd valued, so will come after 2, maintaining their order in the original linked list, forming 1β†’3.

Finally, our resultant segregated linked list will be 2β†’1β†’3.

If our linked list is 2β†’1β†’6β†’4β†’8.

Then, while segregating the even and odd nodes of the linked list:

  • The nodes 2, 6, 4 and 8 are even valued, so they will come in front, maintaining their order in the original linked list, forming 2β†’6β†’4β†’8.
  • The nodes 1 is odd valued, so it will come after 2, 6, 4 and 8 maintaining its order in the original linked list, forming 1.

Finally, our resultant segregated linked list will be 2β†’6β†’4β†’8β†’1.

Now, I think from the above two examples that it is clear what we have to do in the problems.

Now the main question is how to approach this problem? Try to come up with some approach, not necessarily the optimized one but any approach (if It's brute force it's okay, no problem we will optimize it together).

Well, the most naive idea is to create a new LinkedList by storing the values of the original LinkedList and then inserting the nodes with even value first and then the nodes with odd values, but this will take extra space.

In the above approach we can see that we were able to solve the problem in O(n) time but space complexity is also O(n), so now we need to avoid this extra space.

Note: Generally whenever you get a question on an arrangement in a LinkedList avoid dealing with data rather than try to think of a solution using the manipulation of links.

Let’s try to think of some better approach.

Approach

The idea is to split the linked list into two parts containing only even nodes and the other containing only odd nodes. The only task then we will perform is to join these two linked lists together. Let’s see this in algorithm form.

Algorithm

Traverse the linked list:

  • For every odd valued node, remove that node from the original linked list and place it in another linked list.
  • Continue this till the end of the linked list, and then we will be left with our original linked list containing only the even nodes and another linked list with odd nodes.
  • Join these two linked lists and return the head of this linked list.

Dry Run

Code Implementation



#include 
struct Node
{
    int data;
    struct Node *next;
};
void segregateEvenOdd(struct Node **head_ref)
{
    Node *evenStart = NULL;
    Node *evenEnd = NULL;
    Node *oddStart = NULL;
    Node *oddEnd = NULL;
    Node *currNode = *head_ref;
    
    while(currNode != NULL){
        int val = currNode -> data;
        if(val % 2 == 0) {
            if(evenStart == NULL){
                evenStart = currNode;
                evenEnd = evenStart;
            }
            
            else{
                evenEnd -> next = currNode;
                evenEnd = evenEnd -> next;
            }
        }
        else{
            if(oddStart == NULL){
                oddStart = currNode;
                oddEnd = oddStart;
            }
            else{
                oddEnd -> next = currNode;
                oddEnd = oddEnd -> next;
            }
        }
        currNode = currNode -> next;
    }
    if(oddStart == NULL || evenStart == NULL){
        return;
    }
    evenEnd -> next = oddStart;
    oddEnd -> next = NULL;
    *head_ref = evenStart;
}
void push(struct Node** head_ref, int new_data)
{
    struct Node* new_node = new Node();
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}
void printList(struct Node *node)
{
    while (node!=NULL)
    {
        cout<data;
        node = node->next;
    }
}
int main()
{
    struct Node* head = NULL;
    push(&head, 3);
    push(&head, 2);
    push(&head, 1);
    segregateEvenOdd(&head);
    return 0;
}

Output

2 1 3

Time Complexity: O(n), where n is the size of the LinkedList.
Space Complexity: O(1), no extra space is used.

This blog tried to explain how to segregate even and odd nodes in a linked list by changing the links of the nodes and not by manipulating the data. As we know, if the nodes contain large data then manipulating data is very expensive and hence changing links is preferred. If you want to practice more questions on linked lists, feel free to solve them at Linked List.

Previous post Identical Linked Lists
Next post Check whether the length of given linked list is Even or Odd

Leave a Reply

Your email address will not be published. Required fields are marked *