Move all occurrences of an element to end in a linked list

3.2

Given a linked list and a key in it, the task is to move all occurrences of given key to end of linked list, keeping order of all other elements same.

Examples:

Input  : 1 -> 2 -> 2 -> 4 -> 3
         key = 2 
Output : 1 -> 4 -> 3 -> 2 -> 2

Input  : 6 -> 6 -> 7 -> 6 -> 3 -> 10
         key = 6
Output : 7 -> 3 -> 10 -> 6 -> 6 -> 6

A simple solution is to one by one find all occurrences of given key in linked list. For every found occurrence, insert it at the end. We do it till all occurrences of given key are moved to end.

Time Complexity : O(n2)

An Efficient Solution is to keep two pointers:
pCrawl => Pointer to traverse the whole list one by one.
pKey => Pointer to an occurrence of key if a key is found. Else same as pCrawl.

We start both of the above pointers from head of linked list. We move pKey only when pKey is not pointing to a key. We always move pCrawl. So when pCrawl and pKey are not same, we must have found a key which lies before pCrawl, so we swap data of pCrawl and pKey, and move pKey to next location. The loop invariant is, after swapping of data, all elements from pKey to pCrawl are keys.

Below is the C++ implementation of this approach.

// C++ program to move all occurrences of a
// given key to end.
#include<bits/stdc++.h>

// A Linked list Node
struct Node
{
    int data;
    struct Node* next;
};

// A urility function to create a new node.
struct Node *newNode(int x)
{
   Node *temp = new Node;
   temp->data = x;
   temp->next = NULL;
}

// Utility function to print the elements
// in Linked list
void printList(Node *head)
{
    struct Node* temp = head;
    while (temp != NULL)
    {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

// Moves all occurrences of given key to
// end of linked list.
void moveToEnd(Node *head, int key)
{
    // Keeps track of locations where key
    // is present.
    struct Node *pKey = head;

    // Traverse list
    struct Node *pCrawl = head;
    while (pCrawl != NULL)
    {
        // If current pointer is not same as pointer
        // to a key location, then we must have found
        // a key in linked list. We swap data of pCrawl
        // and pKey and move pKey to next position.
        if (pCrawl != pKey && pCrawl->data != key)
        {
            pKey->data = pCrawl->data;
            pCrawl->data = key;
            pKey = pKey->next;
        }

        // Find next position where key is present
        if (pKey->data != key)
            pKey = pKey->next;

        // Moving to next Node
        pCrawl = pCrawl->next;
    }
}

// Driver code
int main()
{
    Node *head = newNode(10);
    head->next = newNode(20);
    head->next->next = newNode(10);
    head->next->next->next = newNode(30);
    head->next->next->next->next = newNode(40);
    head->next->next->next->next->next = newNode(10);
    head->next->next->next->next->next->next = newNode(60);

    printf("Before moveToEnd(), the Linked list is\n");
    printList(head);

    int key = 10;
    moveToEnd(head, key);

    printf("\nAfter moveToEnd(), the Linked list is\n");
    printList(head);

    return 0;
}

Output:

Before moveToEnd(), the Linked list is
10 20 10 30 40 10 60 

After moveToEnd(), the Linked list is
20 30 40 60 10 10 10 

Time Complexity : O(n) requires only one traversal of list.

Another Efficient Solution is to maintain a separate list of keys. We initialize this list of keys as empty. We traverse given list. For every key found, we remove it from the original list and insert into the separate list of keys. We finally link list of keys at the end of remaining given list. Time complexity of this solution is also O(n) and it also requires only one traversal of list.

This article is contributed by MAZHAR IMAM KHAN. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



3.2 Average Difficulty : 3.2/5.0
Based on 19 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.