Programa en C para la división alterna de un conjunto de listas 1 con enlaces simples dados

Escriba una función AlternatingSplit() que tome una lista y divida sus Nodes para hacer dos listas más pequeñas ‘a’ y ‘b’. Las sublistas deben estar hechas de elementos alternos en la lista original. Entonces, si la lista original es 0->1->0->1->0->1, entonces una sublista debería ser 0->0->0 y la otra debería ser 1->1->1.

Método 1 (simple): 
el enfoque más simple itera sobre la lista de fuentes y extrae Nodes de la fuente y alternativamente los coloca al frente (o al principio) de ‘a’ y b’. La única parte extraña es que los Nodes estarán en el orden inverso al que ocurrió en la lista de origen. El método 2 inserta el Node al final haciendo un seguimiento del último Node en las sublistas.

C

/* C Program to alternatively split a 
   linked list into two halves */
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
  
// Link list node 
struct Node
{
    int data;
    struct Node* next;
};
  
/* Pull off the front node of the 
   source and put it in dest */
void MoveNode(struct Node** destRef, 
              struct Node** sourceRef) ;
  
/* Given the source list, split its nodes 
   into two shorter lists. If we number the 
   elements 0, 1, 2, ... then all the even 
   elements should go in the first list, and 
   all the odd elements in the second. The 
   elements in the new lists may be in any order. */
void AlternatingSplit(struct Node* source, 
                      struct Node** aRef, 
                      struct Node** bRef) 
{
  /* Split the nodes of source to 
     these 'a' and 'b' lists */
  struct Node* a = NULL; 
  struct Node* b = NULL;
    
  struct Node* current = source;
  while (current != NULL) 
  {
    // Move a node to list 'a' 
    MoveNode(&a, &t); 
    if (current != NULL) 
    {
       // Move a node to list 'b' 
       MoveNode(&b, &t); 
    }
  }
  *aRef = a;
  *bRef = b;
}
  
/* Take the node from the front of the source, 
   and move it to the front of the dest. It is 
   an error to call this with the source list 
   empty.    
   Before calling MoveNode():
   source == {1, 2, 3}   
   dest == {1, 2, 3}      
   After calling MoveNode():
   source == {2, 3}      
   dest == {1, 1, 2, 3} */
void MoveNode(struct Node** destRef, 
              struct Node** sourceRef) 
{
  // The front source node  
  struct Node* newNode = *sourceRef; 
  assert(newNode != NULL);
    
  // Advance the source pointer 
  *sourceRef = newNode->next;
    
  // Link the old dest off the 
  // new node 
  newNode->next = *destRef; 
    
  // Move dest to point to the 
  // new node 
  *destRef = newNode; 
}
  
// Utility Functions
/* Function to insert a node at the 
   beginning of the linked list */
void push(struct node** head_ref, 
          int new_data)
{
  // Allocate node 
  struct Node* new_node =
         (struct Node*) malloc(sizeof(struct Node));
  
  // Put in the data  
  new_node->data = new_data;
  
  // Link the old list off the 
  // new node 
  new_node->next = (*head_ref);     
  
  // Move the head to point to 
  // the new node 
  (*head_ref) = new_node;
}
  
/* Function to print nodes in a 
   given linked list */
void printList(struct Node *node)
{
  while(node != NULL)
  {
   printf("%d ", node->data);
   node = node->next;
  }
} 
  
// Driver code
int main()
{
  // Start with the empty list 
  struct Node* head = NULL;
  struct Node* a = NULL;
  struct Node* b = NULL;  
  
  /* Let us create a sorted linked list 
     to test the functions
     Created linked list will be 
     0->1->2->3->4->5 */
  push(&head, 5);
  push(&head, 4);
  push(&head, 3);
  push(&head, 2);
  push(&head, 1);                                    
  push(&head, 0);  
  
  printf("
  Original linked List:  ");
  printList(head); 
  
  // Remove duplicates from linked list 
  AlternatingSplit(head, &a, &b); 
  
  printf("
  Resultant Linked List 'a' ");
  printList(a);            
  
  printf("
  Resultant Linked List 'b' ");
  printList(b);            
  
  getchar();
  return 0;
}

Producción:

Original linked List: 0 1 2 3 4 5 
Resultant Linked List 'a' : 4 2 0 
Resultant Linked List 'b' : 5 3 1

Complejidad de tiempo: O(n) donde n es un número de Nodes en la lista enlazada dada.

Método 2 (Uso de Nodes ficticios):
aquí hay un enfoque alternativo que crea las sublistas en el mismo orden que la lista de origen. El código utiliza Nodes de encabezado ficticios temporales para las listas ‘a’ y ‘b’ a medida que se crean. Cada sublista tiene un puntero de «cola» que apunta a su último Node actual, de esa manera se pueden agregar fácilmente nuevos Nodes al final de cada lista. Los Nodes ficticios dan a los punteros de cola algo a lo que apuntar inicialmente. Los Nodes ficticios son eficientes en este caso porque son temporales y están asignados en la pila. Alternativamente, los «punteros de referencia» locales (que siempre apuntan al último puntero de la lista en lugar del último Node) podrían usarse para evitar los Nodes ficticios. 

C

void AlternatingSplit(struct Node* source, 
                      struct Node** aRef, 
                      struct Node** bRef) 
{
  struct Node aDummy;
  
  // Points to the last node in 'a' 
  struct Node* aTail = &aDummy; 
  struct Node bDummy;
  
  // Points to the last node in 'b' 
  struct Node* bTail = &bDummy; 
  struct Node* current = source;
  aDummy.next = NULL;
  bDummy.next = NULL;
  while (current != NULL) 
  {
    // Add at 'a' tail 
    MoveNode(&(aTail->next), &t);
  
    // Advance the 'a' tail 
    aTail = aTail->next; 
    if (current != NULL) 
    {
      MoveNode(&(bTail->next), &t);
      bTail = bTail->next;
    }
  }
  *aRef = aDummy.next;
  *bRef = bDummy.next;
}

Complejidad de tiempo: O(n) donde n es el número de Nodes en la lista enlazada dada.
Fuente: http://cslibrary.stanford.edu/105/LinkedListProblems.pdf
Consulte el artículo completo sobre la división alterna de una lista enlazada individual determinada | ¡ Establezca 1 para más detalles!

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 *