Mover todas las ocurrencias de un elemento para terminar en una lista enlazada

Dada una lista enlazada y una clave en ella, la tarea es mover todas las apariciones de la clave dada al final de la lista enlazada, manteniendo igual el orden de todos los demás elementos.

Ejemplos:  

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

Una solución simple es encontrar una por una todas las apariciones de una clave dada en la lista enlazada. Para cada ocurrencia encontrada, insértela al final. Lo hacemos hasta que todas las apariciones de la clave dada se muevan al final.

Complejidad de tiempo: O(n 2 ), ya que usaremos bucles anidados para encontrar el Node con la clave e insertarlo al final de la lista enlazada.
Espacio auxiliar: O(1), ya que no estamos utilizando ningún espacio adicional.

Solución eficiente 1: es mantener dos punteros: 

pCrawl => Puntero para recorrer toda la lista una por una. 
pKey => Puntero a una ocurrencia de la clave si se encuentra una clave. De lo contrario, lo mismo que pCrawl.

Comenzamos los dos punteros anteriores desde el encabezado de la lista enlazada. Movemos pKey solo cuando pKey no apunta a una tecla. Siempre movemos pCrawl . Entonces, cuando pCrawl y pKey no son lo mismo, debemos haber encontrado una clave que se encuentra antes de pCrawl , por lo que intercambiamos entre pCrawl y pKey , y movemos pKey a la siguiente ubicación. El ciclo invariable es que, después del intercambio de datos, todos los elementos desde pKey hasta pCrawl son claves.

A continuación se muestra la implementación de este enfoque.  

C++

// 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 utility 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;
}

Java

// Java program to move all occurrences of a
// given key to end.
class GFG {
 
    // A Linked list Node
    static class Node {
        int data;
        Node next;
    }
 
    // A utility function to create a new node.
    static Node newNode(int x)
    {
        Node temp = new Node();
        temp.data = x;
        temp.next = null;
        return temp;
    }
 
    // Utility function to print the elements
    // in Linked list
    static void printList(Node head)
    {
        Node temp = head;
        while (temp != null) {
            System.out.printf("%d ", temp.data);
            temp = temp.next;
        }
        System.out.printf("\n");
    }
 
    // Moves all occurrences of given key to
    // end of linked list.
    static void moveToEnd(Node head, int key)
    {
        // Keeps track of locations where key
        // is present.
        Node pKey = head;
 
        // Traverse list
        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
    public static void main(String args[])
    {
        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);
 
        System.out.printf("Before moveToEnd(), the Linked list is\n");
        printList(head);
 
        int key = 10;
        moveToEnd(head, key);
 
        System.out.printf("\nAfter moveToEnd(), the Linked list is\n");
        printList(head);
    }
}
 
// This code is contributed by Arnab Kundu

Python3

# Python3 program to move all occurrences of a
# given key to end.
 
# Linked List node
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
 
# A utility function to create a new node.
def newNode(x):
 
    temp = Node(0)
    temp.data = x
    temp.next = None
    return temp
 
# Utility function to print the elements
# in Linked list
def printList( head):
 
    temp = head
    while (temp != None) :
        print( temp.data,end = " ")
        temp = temp.next
     
    print()
 
# Moves all occurrences of given key to
# end of linked list.
def moveToEnd(head, key):
 
    # Keeps track of locations where key
    # is present.
    pKey = head
 
    # Traverse list
    pCrawl = head
    while (pCrawl != None) :
         
        # 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 and 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
     
    return head
 
# Driver code
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)
 
print("Before moveToEnd(), the Linked list is\n")
printList(head)
 
key = 10
head = moveToEnd(head, key)
 
print("\nAfter moveToEnd(), the Linked list is\n")
printList(head)
 
# This code is contributed by Arnab Kundu

C#

// C# program to move all occurrences of a
// given key to end.
using System;
 
class GFG {
 
    // A Linked list Node
    public class Node {
        public int data;
        public Node next;
    }
 
    // A utility function to create a new node.
    static Node newNode(int x)
    {
        Node temp = new Node();
        temp.data = x;
        temp.next = null;
        return temp;
    }
 
    // Utility function to print the elements
    // in Linked list
    static void printList(Node head)
    {
        Node temp = head;
        while (temp != null) {
            Console.Write("{0} ", temp.data);
            temp = temp.next;
        }
        Console.Write("\n");
    }
 
    // Moves all occurrences of given key to
    // end of linked list.
    static void moveToEnd(Node head, int key)
    {
        // Keeps track of locations where key
        // is present.
        Node pKey = head;
 
        // Traverse list
        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
    public static void Main(String[] args)
    {
        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);
 
        Console.Write("Before moveToEnd(), the Linked list is\n");
        printList(head);
 
        int key = 10;
        moveToEnd(head, key);
 
        Console.Write("\nAfter moveToEnd(), the Linked list is\n");
        printList(head);
    }
}
 
// This code has been contributed by 29AjayKumar

Javascript

<script>
 
// Javascript program to move all occurrences of a
// given key to end.   
 
// A Linked list Node
    class Node {
        constructor() {
               this.data = 0;
            this.next = null;
        }
    }
 
    // A utility function to create a new node.
    function newNode(x) {
        var temp = new Node();
        temp.data = x;
        temp.next = null;
        return temp;
    }
 
    // Utility function to print the elements
    // in Linked list
    function printList(head) {
        var temp = head;
        while (temp != null) {
            document.write( temp.data+" ");
            temp = temp.next;
        }
        document.write("<br/>");
    }
 
    // Moves all occurrences of given key to
    // end of linked list.
    function moveToEnd(head , key) {
        // Keeps track of locations where key
        // is present.
        var pKey = head;
 
        // Traverse list
        var 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
     
        var 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);
 
        document.write(
        "Before moveToEnd(), the Linked list is<br/>"
        );
        printList(head);
 
        var key = 10;
        moveToEnd(head, key);
 
        document.write(
        "<br/>After moveToEnd(), the Linked list is<br/>"
        );
        printList(head);
 
// This code contributed by umadevi9616
 
</script>
Producción

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 

Complejidad de tiempo: O (n), ya que estamos usando un bucle para atravesar n veces. Donde n es el número de Nodes en la lista enlazada.
Espacio auxiliar: O(1) , ya que no estamos utilizando ningún espacio adicional.

Solución eficiente 2: 

  1. Recorra la lista enlazada y tome un puntero en la cola. 
  2. Ahora, busque la clave y el Node->datos. Si son iguales, mueva el Node al último-siguiente, de lo contrario avance.

C++

// C++ code to remove key element to end of linked list
#include<bits/stdc++.h>
using namespace std;
 
// A Linked list Node
struct Node
{
    int data;
    struct Node* next;
};
 
// A utility function to create a new node.
struct Node* newNode(int x)
{
    Node* temp = new Node;
    temp->data = x;
    temp->next = NULL;
}
 
// Function to remove key to end
Node *keyToEnd(Node* head, int key)
{
 
    // Node to keep pointing to tail
    Node* tail = head;
    if (head == NULL)
    {
        return NULL;
    }
    while (tail->next != NULL)
    {
        tail = tail->next;
    }
     
    // Node to point to last of linked list
    Node* last = tail;
    Node* current = head;
    Node* prev = NULL;
     
    // Node prev2 to point to previous when head.data!=key
    Node* prev2 = NULL;
     
    // loop to perform operations to remove key to end
    while (current != tail)
    {
        if (current->data == key && prev2 == NULL)
        {
            prev = current;
            current = current->next;
            head = current;
            last->next = prev;
            last = last->next;
            last->next = NULL;
            prev = NULL;
        }
        else
        {
            if (current->data == key && prev2 != NULL)
            {
                prev = current;
                current = current->next;
                prev2->next = current;
                last->next = prev;
                last = last->next;
                last->next = NULL;
            }
            else if (current != tail)
            {
                prev2 = current;
                current = current->next;
            }
        }
    }
    return head;
}
 
// Function to display linked list
void printList(Node* head)
{
    struct Node* temp = head;
    while (temp != NULL)
    {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}
 
 
// Driver Code
int main()
{
    Node* root = newNode(5);
    root->next = newNode(2);
    root->next->next = newNode(2);
    root->next->next->next = newNode(7);
    root->next->next->next->next = newNode(2);
    root->next->next->next->next->next = newNode(2);
    root->next->next->next->next->next->next = newNode(2);
 
    int key = 2;
    cout << "Linked List before operations :";
    printList(root);
    cout << "\nLinked List after operations :";
    root = keyToEnd(root, key);
    printList(root);
    return 0;
}
 
// This code is contributed by Rajout-Ji

Java

// Java code to remove key element to end of linked list
import java.util.*;
 
// Node class
class Node {
    int data;
    Node next;
 
    public Node(int data)
    {
        this.data = data;
        this.next = null;
    }
}
 
class gfg {
 
    static Node root;
 
    // Function to remove key to end
    public static Node keyToEnd(Node head, int key)
    {
 
        // Node to keep pointing to tail
        Node tail = head;
 
        if (head == null) {
            return null;
        }
 
        while (tail.next != null) {
            tail = tail.next;
        }
 
        // Node to point to last of linked list
        Node last = tail;
 
        Node current = head;
        Node prev = null;
 
        // Node prev2 to point to previous when head.data!=key
        Node prev2 = null;
 
        // loop to perform operations to remove key to end
        while (current != tail) {
            if (current.data == key && prev2 == null) {
                prev = current;
                current = current.next;
                head = current;
                last.next = prev;
                last = last.next;
                last.next = null;
                prev = null;
            }
            else {
                if (current.data == key && prev2 != null) {
                    prev = current;
                    current = current.next;
                    prev2.next = current;
                    last.next = prev;
                    last = last.next;
                    last.next = null;
                }
                else if (current != tail) {
                    prev2 = current;
                    current = current.next;
                }
            }
        }
        return head;
    }
 
    // Function to display linked list
    public static void display(Node root)
    {
        while (root != null) {
            System.out.print(root.data + " ");
            root = root.next;
        }
    }
 
    // Driver Code
    public static void main(String args[])
    {
        root = new Node(5);
        root.next = new Node(2);
        root.next.next = new Node(2);
        root.next.next.next = new Node(7);
        root.next.next.next.next = new Node(2);
        root.next.next.next.next.next = new Node(2);
        root.next.next.next.next.next.next = new Node(2);
 
        int key = 2;
        System.out.println("Linked List before operations :");
        display(root);
        System.out.println("\nLinked List after operations :");
        root = keyToEnd(root, key);
        display(root);
    }
}

Python3

# Python3 code to remove key element to
# end of linked list
  
# A Linked list Node
class Node:
     
    def __init__(self, data):
         
        self.data = data
        self.next = None
         
# A utility function to create a new node.
def newNode(x):
     
    temp = Node(x)
    return temp
 
# Function to remove key to end
def keyToEnd(head, key):
 
    # Node to keep pointing to tail
    tail = head
     
    if (head == None):
        return None
     
    while (tail.next != None):
        tail = tail.next
     
    # Node to point to last of linked list
    last = tail
    current = head
    prev = None
      
    # Node prev2 to point to previous
    # when head.data!=key
    prev2 = None
      
    # Loop to perform operations to
    # remove key to end
    while (current != tail):
        if (current.data == key and prev2 == None):
            prev = current
            current = current.next
            head = current
            last.next = prev
            last = last.next
            last.next = None
            prev = None
 
        else:
            if (current.data == key and prev2 != None):
                prev = current
                current = current.next
                prev2.next = current
                last.next = prev
                last = last.next
                last.next = None
             
            else if (current != tail):
                prev2 = current
                current = current.next
                 
    return head
 
# Function to display linked list
def printList(head):
 
    temp = head
     
    while (temp != None):
        print(temp.data, end = ' ')
        temp = temp.next
     
    print()
     
# Driver Code
if __name__=='__main__':
     
    root = newNode(5)
    root.next = newNode(2)
    root.next.next = newNode(2)
    root.next.next.next = newNode(7)
    root.next.next.next.next = newNode(2)
    root.next.next.next.next.next = newNode(2)
    root.next.next.next.next.next.next = newNode(2)
  
    key = 2
    print("Linked List before operations :")
    printList(root)
    print("Linked List after operations :")
    root = keyToEnd(root, key)
     
    printList(root)
     
# This code is contributed by rutvik_56

C#

// C# code to remove key
// element to end of linked list
using System;
 
// Node class
public class Node {
    public int data;
    public Node next;
 
    public Node(int data)
    {
        this.data = data;
        this.next = null;
    }
}
 
class GFG {
 
    static Node root;
 
    // Function to remove key to end
    public static Node keyToEnd(Node head, int key)
    {
 
        // Node to keep pointing to tail
        Node tail = head;
 
        if (head == null) {
            return null;
        }
 
        while (tail.next != null) {
            tail = tail.next;
        }
 
        // Node to point to last of linked list
        Node last = tail;
 
        Node current = head;
        Node prev = null;
 
        // Node prev2 to point to
        // previous when head.data!=key
        Node prev2 = null;
 
        // loop to perform operations
        // to remove key to end
        while (current != tail) {
            if (current.data == key && prev2 == null) {
                prev = current;
                current = current.next;
                head = current;
                last.next = prev;
                last = last.next;
                last.next = null;
                prev = null;
            }
            else {
                if (current.data == key && prev2 != null) {
                    prev = current;
                    current = current.next;
                    prev2.next = current;
                    last.next = prev;
                    last = last.next;
                    last.next = null;
                }
                else if (current != tail) {
                    prev2 = current;
                    current = current.next;
                }
            }
        }
        return head;
    }
 
    // Function to display linked list
    public static void display(Node root)
    {
        while (root != null) {
            Console.Write(root.data + " ");
            root = root.next;
        }
    }
 
    // Driver Code
    public static void Main()
    {
        root = new Node(5);
        root.next = new Node(2);
        root.next.next = new Node(2);
        root.next.next.next = new Node(7);
        root.next.next.next.next = new Node(2);
        root.next.next.next.next.next = new Node(2);
        root.next.next.next.next.next.next = new Node(2);
 
        int key = 2;
        Console.WriteLine("Linked List before operations :");
        display(root);
        Console.WriteLine("\nLinked List after operations :");
        root = keyToEnd(root, key);
        display(root);
    }
}
 
// This code is contributed by PrinciRaj1992

Javascript

<script>
// javascript code to remove key element to end of linked list// Node class
    class Node {
        constructor(val) {
            this.data = val;
            this.next = null;
        }
    }
    var root;
 
    // Function to remove key to end
    function keyToEnd(head , key) {
 
        // Node to keep pointing to tail
        var tail = head;
 
        if (head == null) {
            return null;
        }
 
        while (tail.next != null) {
            tail = tail.next;
        }
 
        // Node to point to last of linked list
        var last = tail;
 
        var current = head;
        var prev = null;
 
        // Node prev2 to point to previous when head.data!=key
        var prev2 = null;
 
        // loop to perform operations to remove key to end
        while (current != tail) {
            if (current.data == key && prev2 == null) {
                prev = current;
                current = current.next;
                head = current;
                last.next = prev;
                last = last.next;
                last.next = null;
                prev = null;
            } else {
                if (current.data == key && prev2 != null) {
                    prev = current;
                    current = current.next;
                    prev2.next = current;
                    last.next = prev;
                    last = last.next;
                    last.next = null;
                } else if (current != tail) {
                    prev2 = current;
                    current = current.next;
                }
            }
        }
        return head;
    }
 
    // Function to display linked list
    function display(root) {
        while (root != null) {
            document.write(root.data + " ");
            root = root.next;
        }
    }
 
    // Driver Code
     
        root = new Node(5);
        root.next = new Node(2);
        root.next.next = new Node(2);
        root.next.next.next = new Node(7);
        root.next.next.next.next = new Node(2);
        root.next.next.next.next.next = new Node(2);
        root.next.next.next.next.next.next = new Node(2);
 
        var key = 2;
        document.write("Linked List before operations :<br/>");
        display(root);
        document.write("<br/>Linked List after operations :<br/>");
        root = keyToEnd(root, key);
        display(root);
 
// This code contributed by aashish1995
</script>
Producción

Linked List before operations :5 2 2 7 2 2 2 

Linked List after operations :5 7 2 2 2 2 2 

Complejidad de tiempo: O (n), ya que estamos usando un bucle para atravesar n veces. Donde n es el número de Nodes en la lista enlazada.
Espacio auxiliar: O(1), ya que no estamos utilizando ningún espacio adicional.

Gracias a Ravinder Kumar por sugerir este método.

Solución eficiente 3: es mantener una lista separada de claves. Inicializamos esta lista de claves como vacía. Recorremos la lista dada. Por cada clave encontrada, la eliminamos de la lista original y la insertamos en una lista separada de claves. Finalmente vinculamos la lista de claves al final de la lista restante.

Complejidad de tiempo: O (n), ya que estamos usando un bucle para atravesar n veces. Donde n es el número de Nodes en la lista enlazada.
Espacio Auxiliar: O(1 ), ya que no estamos usando ningún espacio extra.

Este artículo es una contribución de MAZHAR IMAM KHAN. Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *