Esta es una pregunta de programación que se hace durante una prueba escrita para una entrevista. "Tiene dos listas vinculadas individualmente que ya están ordenadas, debe fusionarlas y devolver un encabezado de la nueva lista sin crear nuevos nodos adicionales. La lista devuelta también debe ordenarse"
La firma del método es: Node MergeLists (Node list1, Node list2);
La clase de nodo está debajo:
class Node{
int data;
Node next;
}
Probé muchas soluciones pero no creé un nodo adicional para atornillar las cosas. Por favor ayuda.
Aquí está la entrada de blog adjunta http://techieme.in/merging-two-sorted-singly-linked-list/
algorithm
singly-linked-list
Dharam
fuente
fuente
Respuestas:
fuente
La recursividad no debería ser necesaria para evitar la asignación de un nuevo nodo:
fuente
if (list1.next == null) list1.next = list2;
puede serlist1.next = list2;
. Dado que elwhile (list1.next != null)
ciclo acaba de terminar, podemos estar seguros de esolist1.next == null
.fuente
Aquí está el algoritmo sobre cómo fusionar dos listas enlazadas ordenadas A y B:
Aquí C será la lista de salida.
fuente
¡Mira mamá, sin recursividad!
fuente
La iteración se puede realizar de la siguiente manera. Complejidad = O (n)
fuente
fuente
Esto se puede hacer sin crear el nodo adicional, con solo otra referencia de nodo pasando a los parámetros (temperatura del nodo).
fuente
Me gustaría compartir cómo pensé la solución ... vi la solución que implica recursividad y son bastante sorprendentes, es el resultado de un pensamiento funcional y modular. Realmente aprecio el compartir.
Me gustaría agregar que la recursividad no funcionará para grandes lits, las llamadas de pila se desbordarán; así que decidí probar el enfoque iterativo ... y esto es lo que obtengo.
El código es bastante autoexplicativo, agregué algunos comentarios en línea para tratar de asegurar esto.
Si no lo recibe, avíseme y mejoraré la legibilidad (tal vez tenga una interpretación engañosa de mi propio código).
}
fuente
Una solución iterativa simple.
fuente
A continuación muestro una solución iterativa. Una solución recursiva sería más compacta, pero como no conocemos la longitud de las listas, la recursividad corre el riesgo de desbordamiento de pila.
La idea básica es similar al paso de combinación en la ordenación por combinación; mantenemos un puntero correspondiente a cada lista de entrada; en cada iteración, avanzamos el puntero correspondiente al elemento más pequeño. Sin embargo, hay una diferencia crucial en la que la mayoría de la gente se tropieza. En la ordenación por fusión, dado que usamos una matriz de resultados, la siguiente posición para insertar es siempre el índice de la matriz de resultados. Para una lista enlazada, necesitamos mantener un puntero al último elemento de la lista ordenada. El puntero puede saltar de una lista de entrada a otra dependiendo de cuál tenga el elemento más pequeño para la iteración actual.
Con eso, el siguiente código debería ser autoexplicativo.
fuente
Código simple en javascript para fusionar dos listas enlazadas en su lugar.
fuente
En primer lugar, comprenda el significado de "sin crear nuevos nodos adicionales" . Según tengo entendido, no significa que no pueda tener puntero (s) que apunten a un nodo (s) existente.
No puede lograrlo sin hablar punteros a nodos existentes, incluso si usa la recursividad para lograr lo mismo, el sistema creará punteros para usted como pilas de llamadas. Es como decirle al sistema que agregue punteros que ha evitado en su código.
Función simple para lograr lo mismo tomando punteros adicionales :
fuente
Consulte la publicación de mi blog para http://www.algorithmsandme.com/2013/10/linked-list-merge-two-sorted-linked.html
fuente
fuente
Aquí hay un ejemplo de trabajo completo que usa la lista enlazada implementada java.util. Puede simplemente copiar y pegar el código a continuación dentro de un método main ().
fuente
Forma recursiva (variante de la respuesta de Stefan)
Considere la siguiente lista vinculada para visualizar esto
2>4
lista A1>3
lista BCasi la misma respuesta (no recursiva) que Stefan pero con un poco más de comentarios / nombre de variable significativo. También se cubrió la lista de enlaces dobles en los comentarios si alguien está interesado
Considere el ejemplo
5->10->15>21 // List1
2->3->6->20 //List2
fuente
Mi opinión sobre la pregunta es la siguiente:
Pseudocódigo:
Código:
fuente
fuente
fuente
:) GlbMP
fuente
public static Node merge(Node h1, Node h2) { Node h3 = new Node(0); Node current = h3; boolean isH1Left = false; boolean isH2Left = false; while (h1 != null || h2 != null) { if (h1.data <= h2.data) { current.next = h1; h1 = h1.next; } else { current.next = h2; h2 = h2.next; } current = current.next; if (h2 == null && h1 != null) { isH1Left = true; break; } if (h1 == null && h2 != null) { isH2Left = true; break; } } if (isH1Left) { while (h1 != null) { current.next = h1; current = current.next; h1 = h1.next; } } if (isH2Left) { while (h2 != null) { current.next = h2; current = current.next; h2 = h2.next; } } h3 = h3.next; return h3; }
fuente
Creé solo un nodo ficticio al principio para ahorrarme muchas condiciones 'si'.
fuente
fuente
fuente
Aquí está el código sobre cómo fusionar dos listas enlazadas ordenadas headA y headB:
fuente