Programa C++ para ordenar una lista vinculada que se ordena alternando órdenes ascendentes y descendentes

Dada una lista enlazada. La lista enlazada está en orden ascendente y descendente alternado. Ordena la lista de manera eficiente. 

Ejemplo: 

Input List: 10 -> 40 -> 53 -> 30 -> 67 -> 12 -> 89 -> NULL
Output List: 10 -> 12 -> 30 -> 40 -> 53 -> 67 -> 89 -> NULL

Input List: 1 -> 4 -> 3 -> 2 -> 5 -> NULL
Output List: 1 -> 2 -> 3 -> 4 -> 5 -> NULL

Solución simple:  
Enfoque: La idea básica es aplicar la ordenación por fusión en la lista enlazada. 
La implementación se analiza en este artículo: Merge Sort for Linked List .
Análisis de Complejidad:  

  • Complejidad de tiempo: el tipo de combinación de lista enlazada toma O (n log n) tiempo. En el árbol de clasificación por fusión, la altura es log n. Ordenar cada nivel tomará O(n) tiempo. Entonces la complejidad del tiempo es O (n log n).
  • Espacio auxiliar: O (n log n), en el árbol de ordenación por combinación, la altura es log n. Almacenar cada nivel ocupará O(n) espacio. Entonces la complejidad del espacio es O (n log n).

Solución eficiente:  
Enfoque:  

  1. Separa dos listas.
  2. Invertir el uno con orden descendente
  3. Combinar ambas listas.

Diagrama: 

A continuación se muestran las implementaciones del algoritmo anterior: 

C++

// C++ program to sort a linked
// list that is alternatively sorted 
// in increasing and decreasing order
#include <bits/stdc++.h>
using namespace std;
  
// Linked list node
struct Node 
{
    int data;
    struct Node* next;
};
  
Node* mergelist(Node* head1, 
                Node* head2);
void splitList(Node* head, 
               Node** Ahead, 
               Node** Dhead);
void reverselist(Node*& head);
  
// This is the main function that 
// sorts the linked list
void sort(Node** head)
{
    // Split the list into lists
    Node *Ahead, *Dhead;
    splitList(*head, &Ahead, &Dhead);
  
    // Reverse the descending linked list
    reverselist(Dhead);
  
    // Merge the two linked lists
    *head = mergelist(Ahead, Dhead);
}
  
// A utility function to create a 
// new node
Node* newNode(int key)
{
    Node* temp = new Node;
    temp->data = key;
    temp->next = NULL;
    return temp;
}
  
// A utility function to reverse a 
// linked list
void reverselist(Node*& head)
{
    Node *prev = NULL, 
         *curr = head, *next;
    while (curr) 
    {
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    head = prev;
}
  
// A utility function to print 
// a linked list
void printlist(Node* head)
{
    while (head != NULL) 
    {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}
  
// A utility function to merge 
// two sorted linked lists
Node* mergelist(Node* head1, 
                Node* head2)
{
    // Base cases
    if (!head1)
        return head2;
    if (!head2)
        return head1;
  
    Node* temp = NULL;
    if (head1->data < head2->data) 
    {
        temp = head1;
        head1->next = mergelist(head1->next, 
                                head2);
    }
    else 
    {
        temp = head2;
        head2->next = mergelist(head1, 
                                head2->next);
    }
    return temp;
}
  
// This function alternatively splits
// a linked list with head as head into two:
// For example, 10->20->30->15->40->7 
// is splitted into 10->30->40 and 20->15->7
// "Ahead" is reference to head of ascending 
// linked list
// "Dhead" is reference to head of descending 
// linked list
void splitList(Node* head, Node** Ahead, 
               Node** Dhead)
{
    // Create two dummy nodes to 
    // initialize heads of two 
    // linked list
    *Ahead = newNode(0);
    *Dhead = newNode(0);
  
    Node* ascn = *Ahead;
    Node* dscn = *Dhead;
    Node* curr = head;
  
    // Link alternate nodes
    while (curr) 
    {
        // Link alternate nodes of ascending 
        // linked list
        ascn->next = curr;
        ascn = ascn->next;
        curr = curr->next;
  
        // Link alternate nodes of descending 
        // linked list
        if (curr) 
        {
            dscn->next = curr;
            dscn = dscn->next;
            curr = curr->next;
        }
    }
  
    ascn->next = NULL;
    dscn->next = NULL;
    *Ahead = (*Ahead)->next;
    *Dhead = (*Dhead)->next;
}
  
// Driver code
int main()
{
    Node* head = newNode(10);
    head->next = newNode(40);
    head->next->next = newNode(53);
    head->next->next->next = 
    newNode(30);
    head->next->next->next->next = 
    newNode(67);
    head->next->next->next->next->next = 
    newNode(12);
    head->next->next->next->next->next->next = 
    newNode(89);
  
    cout << "Given Linked List is " << endl;
    printlist(head);
  
    sort(&head);
  
    cout << "Sorted Linked List is " << endl;
    printlist(head);
  
    return 0;
}

Producción: 

Given Linked List is
10 40 53 30 67 12 89
Sorted Linked List is
10 12 30 40 53 67 89

Análisis de Complejidad:  

  • Complejidad temporal: O(n). 
    Se necesita un recorrido para separar la lista e invertirla. La fusión de listas ordenadas toma O(n) tiempo.
  • Espacio Auxiliar: O(1). 
    No se requiere espacio adicional.

Consulte el artículo completo sobre ¿Ordenar una lista vinculada que se ordena alternando órdenes ascendentes y descendentes? ¡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 *