Programa de Python para reorganizar una lista vinculada dada en el lugar

Dada una lista unida L 0 -> L 1 -> … -> L n-1 -> L n . Reorganice los Nodes en la lista para que la nueva lista formada sea: L 0 -> L n -> L 1 -> L n-1 -> L 2 -> L n-2
Debe hacer esto en su lugar sin alterando los valores de los Nodes. 

Ejemplos: 

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

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

Solución simple:

1) Initialize current node as head.
2) While next of current node is not null, do following
    a) Find the last node, remove it from the end and insert it as next
       of the current node.
    b) Move current to next to next of current

La complejidad temporal de la solución simple anterior es O(n 2 ) donde n es el número de Nodes en la lista enlazada.

Mejor solución: 
1) Copie el contenido de la lista vinculada dada a un vector. 
2) Reorganizar el vector dado intercambiando Nodes de ambos extremos. 
3) Copie el vector modificado nuevamente a la lista enlazada. 
Implementación de este enfoque: https://ide.geeksforgeeks.org/1eGSEy 
Gracias a Arushi Dhamija por sugerir este enfoque.

Solución eficiente:

1) Find the middle point using tortoise and hare method.
2) Split the linked list into two halves using found middle point in step 1.
3) Reverse the second half.
4) Do alternate merge of first and second halves.

La complejidad temporal de esta solución es O(n). 

A continuación se muestra la implementación de este método.

Python3

# Python program to rearrange linked list
# in place
 
# Node Class
class Node:
   
    # Constructor to create
    # a new node
    def __init__(self, d):
        self.data = d
        self.next = None
         
def printlist(node):
    if(node == None):
        return
    while(node != None):
        print(node.data," -> ",
              end = "")
        node = node.next
 
def reverselist(node):
    prev = None
    curr = node
    next=None
    while (curr != None):
        next = curr.next
        curr.next = prev
        prev = curr
        curr = next
    node = prev
    return node
 
def rearrange(node):
   
    # 1) Find the middle point using
    # tortoise and hare method
    slow = node
    fast = slow.next
 
    while (fast != None and
           fast.next != None):
        slow = slow.next
        fast = fast.next.next
     
    # 2) Split the linked list in
    # two halves
    # node1, head of first half   
    # 1 -> 2 -> 3
    # node2, head of second half  
    # 4 -> 5   
    node1 = node
    node2 = slow.next
    slow.next = None
     
    # 3) Reverse the second half,
    # i.e., 5 -> 4
    node2 = reverselist(node2)
     
    # 4) Merge alternate nodes
    # Assign dummy Node
    node = Node(0) 
     
    # curr is the pointer to this
    # dummy Node, which will be
    # used to form the new list
    curr = node
     
    while (node1 != None or
           node2 != None):
         
        # First add the element from
        # first list
        if (node1 != None):
            curr.next = node1
            curr = curr.next
            node1 = node1.next
         
        # Then add the element from
        # second list
        if(node2 != None):
            curr.next = node2
            curr = curr.next
            node2 = node2.next
     
    # Assign the head of the new list
    # to head pointer
    node = node.next
 
head = None
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
 
# Print original list
printlist(head)
 
# Rearrange list as per ques
rearrange(head)
print()
 
# Print modified list
printlist(head)
# This code is contributed by ab2127

Producción:

1 -> 2 -> 3 -> 4 -> 5 
1 -> 5 -> 2 -> 4 -> 3

Complejidad de tiempo: O(n) 
Espacio auxiliar: O(1)
Gracias a Gaurav Ahirwar por sugerir el enfoque anterior.

Otro enfoque: 
1. Tome dos punteros prev y curr, que contienen las direcciones de head y head-> next. 
2. Compare sus datos e intercambie. 
Después de eso, se forma una nueva lista enlazada. 

A continuación se muestra la implementación: 

Python3

# Python3 code to rearrange linked list
# in place
class Node:
 
    def __init__(self, x):
        self.data = x
        self.next = None
 
# Function for rearranging a
# linked list with high and
# low value
def rearrange(head):
 
    # Base case
    if (head == None):
        return head
 
    # Two pointer variable
    prev, curr = head, head.next
 
    while (curr):
 
        # Swap function for swapping
        # data
        if (prev.data > curr.data):
            prev.data, curr.data = curr.data, prev.data
 
        # Swap function for swapping data
        if (curr.next and curr.next.data > curr.data):
            curr.next.data, curr.data = curr.data, curr.next.data
 
        prev = curr.next
 
        if (not curr.next):
            break
 
        curr = curr.next.next
 
    return head
 
# Function to insert a node in the
# linked list at the beginning
def push(head, k):
 
    tem = Node(k)
    tem.data = k
    tem.next = head
    head = tem
    return head
 
# Function to display node of
# linked list
def display(head):
    curr = head
 
    while (curr != None):
        print(curr.data, end = " ")
        curr = curr.next
 
# Driver code
if __name__ == '__main__':
    head = None
 
    # Let create a linked list
    # 9 . 6 . 8 . 3 . 7
    head = push(head, 7)
    head = push(head, 3)
    head = push(head, 8)
    head = push(head, 6)
    head = push(head, 9)
    head = rearrange(head)
    display(head)
# This code is contributed by mohit kumar 29

Producción:

6 9 3 8 7

Complejidad de tiempo: O(n) 
Espacio auxiliar: O(1) 
Gracias a Aditya por sugerir este enfoque.

Otro enfoque: (usando la recursividad)  

  1. Mantenga un puntero en el Node principal y vaya hasta el último Node usando recursividad
  2. Una vez que se alcanza el último Node, comience a intercambiar el último Node con el siguiente Node principal
  3. Mover el puntero de la cabeza al siguiente Node
  4. Repita esto hasta que la cabeza y el último Node se encuentren o queden adyacentes entre sí.
  5. Una vez que se cumplió la condición de parada, debemos descartar los Nodes de la izquierda para corregir el bucle creado en la lista al intercambiar Nodes.

Python3

# Python3 program to implement
# the above approach
class Node:   
    def __init__(self, key):       
        self.data = key
        self.next = None
 
left = None
 
# Function to print the list
def printlist(head):   
    while (head != None):
        print(head.data, end = " ")
        if (head.next != None):
            print("->", end = "")
             
        head = head.next
         
    print()
 
# Function to rearrange
def rearrange(head):   
    global left
    if (head != None):
        left = head
        reorderListUtil(left)
 
def reorderListUtil(right):   
    global left
    if (right == None):
        return
     
    reorderListUtil(right.next)
     
    # We set left = null, when we
    # reach stop condition, so no
    # processing required after that
    if (left == None):
        return
     
    # Stop condition: odd case :
    # left = right, even
    # case : left.next = right
    if (left != right and
        left.next != right):
        temp = left.next
        left.next = right
        right.next = temp
        left = temp
    else:
         
        # Stop condition , set null
        # to left nodes
        if (left.next == right):
             
            # Even case
            left.next.next = None
            left = None
        else:
             
            # Odd case
            left.next = None
            left = None
 
# Driver code
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
 
# Print original list
printlist(head)
 
#  Modify the list
rearrange(head)
 
# Print modified list
printlist(head)
# This code is contributed by patel2127

Producción:

1 ->2 ->3 ->4 ->5 
1 ->5 ->2 ->4 ->3

Complejidad de tiempo: O(n), donde n representa la longitud de la lista enlazada dada.
Espacio auxiliar: O(n), para pila recursiva donde n representa la longitud de la lista enlazada dada.

Consulte el artículo completo sobre Reorganizar una lista vinculada dada en el lugar. ¡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 *