Invertir una lista doblemente enlazada | Conjunto 4 (intercambio de datos)

Dada una lista doblemente enlazada, se nos pide que invirtamos la lista en su lugar sin usar ningún espacio adicional.

Ejemplos: 

Input : 1 <--> 2 <--> 5 <--> 6 <--> 7
Output : 7 <--> 6 <--> 5 <--> 2 <--> 1

Input : 11 <--> 22 <--> 33 <--> 22 <--> 1
Output : 1 <--> 22 <--> 33 <--> 22 <--> 11 

Hemos discutido tres métodos para revertir una lista doblemente enlazada: Revertir una lista doblemente enlazada , Revertir una lista doblemente enlazada (Conjunto 2) e Revertir una lista doblemente enlazada usando recursividad .
Los dos primeros métodos funcionan en tiempo O(n) y no requieren espacio adicional. El primer método funciona intercambiando los punteros siguiente y anterior de cada Node. El segundo método toma cada Node de la lista y lo agrega al principio de la lista.
Hay otro enfoque que es un poco más intuitivo, pero también un poco más costoso. 
Este método es similar a la array inversa. Para invertir una array, colocamos dos punteros, uno al principio y otro al final de la lista. Luego intercambiamos los datos de los dos punteros y avanzamos ambos punteros uno hacia el otro. Nos detenemos cuando los dos punteros se encuentran o cuando se cruzan. Realizamos exactamente n/2 intercambios, y la complejidad del tiempo también es O(N).
Una lista doblemente enlazada tiene un puntero anterior y otro siguiente, lo que significa que podemos recorrer la lista tanto hacia adelante como hacia atrás. Entonces, si colocamos un puntero (por ejemplo, el puntero izquierdo) al principio de la lista y otro puntero derecho al final de la lista, podemos acercar estos punteros haciendo avanzar el puntero izquierdo y retrocediendo el puntero derecho.

Algoritmo:

Step 1: Set LEFT to head of list
Step 2: Traverse the list and set RIGHT to end of the list 
Step 3: Repeat following steps while LEFT != RIGHT and 
        LEFT->PREV != RIGHT
Step 4: Swap LEFT->DATA and RIGHT->DATA
Step 5: Advance LEFT pointer by one, LEFT = LEFT->NEXT
Step 6: Recede RIGHT pointer by one, i.e RIGHT = RIGHT->PREV
        [END OF LOOP]
Step 7: End

Una nota sobre la eficiencia comparativa de los tres métodos 

Algunas cosas deben ser mencionadas. Este método es simple de implementar, pero también es más costoso en comparación con el método de intercambio de punteros. Esto se debe a que intercambiamos datos y no punteros. El intercambio de datos puede resultar más costoso si los Nodes son tipos de datos grandes y complejos con varios miembros de datos. Por el contrario, el puntero al Node siempre será un tipo de datos más simple y de 4 u 8 bytes.

A continuación se muestra la implementación del algoritmo. 

C++

// Cpp Program to Reverse a List using Data Swapping
 
#include <bits/stdc++.h>
using namespace std;
 
struct Node {
    int data;
    struct Node *prev, *next;
};
 
Node* newNode(int val)
{
    Node* temp = new Node;
    temp->data = val;
    temp->prev = temp->next = nullptr;
    return temp;
}
 
void printList(Node* head)
{
    while (head->next != nullptr) {
        cout << head->data << " <--> ";
        head = head->next;
    }
    cout << head->data << endl;
}
 
// Insert a new node at the head of the list
void insert(Node** head, int val)
{
    Node* temp = newNode(val);
    temp->next = *head;
    (*head)->prev = temp;
    (*head) = temp;
}
 
// Function to reverse the list
void reverseList(Node** head)
{
    Node* left = *head, * right = *head;
 
    // Traverse the list and set right pointer to
    // end of list
    while (right->next != nullptr)
        right = right->next;
 
    // Swap data of left and right pointer and move
    // them towards each other until they meet or
    // cross each other
    while (left != right && left->prev != right) {
 
        // Swap data of left and right pointer
        swap(left->data, right->data);
 
        // Advance left pointer
        left = left->next;
 
        // Advance right pointer
        right = right->prev;
    }
}
 
// Driver code
int main()
{
    Node* head = newNode(5);
    insert(&head, 4);
    insert(&head, 3);
    insert(&head, 2);
    insert(&head, 1);
 
    printList(head);
    cout << "List After Reversing" << endl;
    reverseList(&head);
    printList(head);
 
    return 0;
}

C

// C Program to Reverse a List using Data Swapping
#include <stdio.h>
#include <stdlib.h>
 
struct Node {
  int data;
  struct Node* prev;
  struct Node* next;
};
 
// Insert a new node at the head of the list
void insert(struct Node** head, int val)
{
  struct Node* temp;
  temp = (struct Node*)malloc(sizeof(struct Node));
  temp->data = val;
  temp->next = *head;
  temp->prev = NULL;
  if ((*head) != NULL) {
    (*head)->prev = temp;
  }
  (*head) = temp;
}
 
void printList(struct Node* head)
{
  struct Node* temp = head;
  while (temp->next != NULL) {
    printf("%d <--> ", temp->data);
    temp = temp->next;
  }
  printf("%d\n", temp->data);
}
 
// Function to reverse the list
void reverseList(struct Node* head)
{
  struct Node* left = head;
  struct Node* right = head;
 
  // Traverse the list and set right pointer to
  // end of list
  while (right->next != NULL) {
    right = right->next;
  }
 
  // Swap data of left and right pointer and move
  // them towards each other until they meet or
  // cross each other
  while (left != right && left->prev != right) {
 
    // Swap data of left and right pointer
    int temp = left->data;
    left->data = right->data;
    right->data = temp;
 
    // Advance left pointer
    left = left->next;
 
    // Advance right pointer
    right = right->prev;
  }
}
 
int main()
{
 
  // code
  struct Node* head = NULL;
  insert(&head, 5);
  insert(&head, 4);
  insert(&head, 3);
  insert(&head, 2);
  insert(&head, 1);
 
  printList(head);
  printf("List After Reversing\n");
 
  reverseList(head);
  printList(head);
 
  return 0;
 
  // This code is contributed by lokesh (lokeshmvs21)
}

Java

// Java Program to Reverse a List using Data Swapping
class GFG
{
static class Node
{
    int data;
    Node prev, next;
};
 
static Node newNode(int val)
{
    Node temp = new Node();
    temp.data = val;
    temp.prev = temp.next = null;
    return temp;
}
 
static void printList(Node head)
{
    while (head.next != null)
    {
        System.out.print(head.data+ " <-> ");
        head = head.next;
    }
    System.out.println( head.data );
}
 
// Insert a new node at the head of the list
static Node insert(Node head, int val)
{
    Node temp = newNode(val);
    temp.next = head;
    (head).prev = temp;
    (head) = temp;
    return head;
}
 
// Function to reverse the list
static Node reverseList(Node head)
{
    Node left = head, right = head;
 
    // Traverse the list and set right pointer to
    // end of list
    while (right.next != null)
        right = right.next;
 
    // Swap data of left and right pointer and move
    // them towards each other until they meet or
    // cross each other
    while (left != right && left.prev != right)
    {
 
        // Swap data of left and right pointer
        int t = left.data;
        left.data = right.data;
        right.data = t;
 
        // Advance left pointer
        left = left.next;
 
        // Advance right pointer
        right = right.prev;
    }
    return head;
}
 
// Driver code
public static void main(String args[])
{
    Node head = newNode(5);
    head = insert(head, 4);
    head = insert(head, 3);
    head = insert(head, 2);
    head = insert(head, 1);
 
    printList(head);
    System.out.println("List After Reversing");
    head=reverseList(head);
    printList(head);
 
}
}
 
// This code is contributed by Arnab Kundu

Python3

# Python3 Program to Reverse a List
# using Data Swapping
import math
 
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
 
def newNode(val):
    temp = Node(val)
    temp.data = val
    temp.prev =None
    temp.next = None
    return temp
 
def printList( head):
    while (head.next != None):
        print(head.data, end = "<-->")
        head = head.next
     
    print(head.data)
 
# Insert a new node at the head of the list
def insert(head, val):
    temp = newNode(val)
    temp.next = head
    (head).prev = temp
    (head) = temp
    return head
 
# Function to reverse the list
def reverseList( head):
    left = head
    right = head
 
    # Traverse the list and set right
    # pointer to end of list
    while (right.next != None):
        right = right.next
 
    # Swap data of left and right pointer
    # and move them towards each other
    # until they meet or cross each other
    while (left != right and left.prev != right):
 
        # Swap data of left and right pointer
        t = left.data
        left.data = right.data
        right.data = t
         
        # Advance left pointer
        left = left.next
 
        # Advance right pointer
        right = right.prev
     
    return head
 
# Driver code
if __name__=='__main__':
 
    head = newNode(5)
    head = insert(head, 4)
    head = insert(head, 3)
    head = insert(head, 2)
    head = insert(head, 1)
 
    printList(head)
    print("List After Reversing")
    head = reverseList(head)
    printList(head)
 
# This code is contributed by AbhiThakur

C#

// C# Program to Reverse a List using Data Swapping
using System;
 
class GFG
{
 
    public class Node
    {
        public int data;
        public Node prev, next;
    };
     
    static Node newNode(int val)
    {
        Node temp = new Node();
        temp.data = val;
        temp.prev = temp.next = null;
        return temp;
    }
     
    static void printList(Node head)
    {
        while (head.next != null)
        {
            Console.Write(head.data+ " <-> ");
            head = head.next;
        }
        Console.WriteLine( head.data );
    }
     
    // Insert a new node at the head of the list
    static Node insert(Node head, int val)
    {
        Node temp = newNode(val);
        temp.next = head;
        (head).prev = temp;
        (head) = temp;
        return head;
    }
     
    // Function to reverse the list
    static Node reverseList(Node head)
    {
        Node left = head, right = head;
     
        // Traverse the list and set right pointer to
        // end of list
        while (right.next != null)
            right = right.next;
     
        // Swap data of left and right pointer and move
        // them towards each other until they meet or
        // cross each other
        while (left != right && left.prev != right)
        {
     
            // Swap data of left and right pointer
            int t = left.data;
            left.data = right.data;
            right.data = t;
     
            // Advance left pointer
            left = left.next;
     
            // Advance right pointer
            right = right.prev;
        }
        return head;
    }
     
    // Driver code
    public static void Main(String []args)
    {
        Node head = newNode(5);
        head = insert(head, 4);
        head = insert(head, 3);
        head = insert(head, 2);
        head = insert(head, 1);
     
        printList(head);
        Console.WriteLine("List After Reversing");
        head=reverseList(head);
        printList(head);
     
    }
}
 
// This code has been contributed by 29AjayKumar

Javascript

<script>
    // javascript Program to Reverse a List using Data Swapping
 
    class Node {
        constructor(val) {
            this.data = val;
            this.prev = null;
            this.next = null;
        }
    }
 
    function newNode(val) {
        var temp = new Node();
        temp.data = val;
        temp.prev = temp.next = null;
        return temp;
    }
 
    function printList(head) {
        while (head.next != null) {
            document.write(head.data + " <-> ");
            head = head.next;
        }
        document.write(head.data);
    }
 
    // Insert a new node at the head of the list
    function insert(head , val) {
        var temp = newNode(val);
        temp.next = head;
        (head).prev = temp;
        (head) = temp;
        return head;
    }
 
    // Function to reverse the list
    function reverseList(head) {
        var left = head, right = head;
 
        // Traverse the list and set right pointer to
        // end of list
        while (right.next != null)
            right = right.next;
 
        // Swap data of left and right pointer and move
        // them towards each other until they meet or
        // cross each other
        while (left != right && left.prev != right) {
 
            // Swap data of left and right pointer
            var t = left.data;
            left.data = right.data;
            right.data = t;
 
            // Advance left pointer
            left = left.next;
 
            // Advance right pointer
            right = right.prev;
        }
        return head;
    }
 
    // Driver code
     
    var head = newNode(5);
    head = insert(head, 4);
    head = insert(head, 3);
    head = insert(head, 2);
    head = insert(head, 1);
 
    printList(head);
    document.write("<br/>List After Reversing<br/>");
    head = reverseList(head);
    printList(head);
 
 
// This code contributed by umadevi9616
</script>
Producción

1 <--> 2 <--> 3 <--> 4 <--> 5
List After Reversing
5 <--> 4 <--> 3 <--> 2 <--> 1

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.

Publicación traducida automáticamente

Artículo escrito por Sayan Mahapatra 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 *