Rony Porraz Vargas
David Cruz Portilla
Se vienen recuerdos del callback hell jajaja
Christian Velázquez
Buen aporte.
Domina la lógica de una linked list al implementar los métodos append y prepend para agregar nodos al final y al inicio. Conecta correctamente la cabeza, la cola y el puntero next para que la estructura crezca sin errores y valida la longitud paso a paso con pruebas simples.
¿Cómo agregar nodos al final con append?
Para que un nuevo nodo sea la nueva cola, la secuencia es directa: crear el nodo, enlazarlo con el tail.next y actualizar la cola. Así logras que el null final se reemplace por el nuevo nodo y la lista crezca de forma consistente.
class Node { constructor(value) { this.value = value; this.next = null; } } class LinkedList { constructor(initialValue) { const firstNode = new Node(initialValue); this.head = firstNode; this.tail = firstNode; this.length = 1; } append(value) { const newNode = new Node(value); this.tail.next = newNode; // enlaza el último nodo actual con el nuevo this.tail = newNode; // el nuevo nodo se convierte en la cola this.length++; return this; } }
¿Cuál es la lógica de tail.next y cola?
¿Cómo validar la estructura y la longitud?
¿Cómo insertar al inicio con prepend?
Para agregar un nodo como nueva cabeza, primero lo conectas al inicio y luego actualizas la referencia de la cabeza. La clave: apuntar el newNode.next al head actual y después mover la cabeza al newNode.
class LinkedList { // ... mismo constructor y Node que arriba prepend(value) { const newNode = new Node(value); newNode.next = this.head; // conecta el nuevo nodo con la cabeza actual this.head = newNode; // el nuevo nodo se convierte en la cabeza this.length++; return this; } }
¿Qué cambia en la cabeza y los pointers?
¿Qué se observa al probar con cero como nueva cabeza?
¿Qué habilidades y keywords refuerzas con esta práctica?
Comprendes cómo modelar una linked list con una clase que mantiene referencias a head, tail y length, y cómo un nodo encapsula value y next. Practicas el manejo de pointers para insertar correctamente sin romper la estructura. Además, validas el estado tras cada operación con retornos tipo return this y pruebas en el navegador.
Si ya implementaste tu método, comparte tu solución y explica cómo llegaste a ella: así todos aprendemos más rápido.
Rony Porraz Vargas
David Cruz Portilla
Se vienen recuerdos del callback hell jajaja
Christian Velázquez
Buen aporte.
Fernando Quinteros Gutierrez
Rogelio Samuel Moreno Corrales
Nicolas Castañeda
Primero muchismas gracias me ayudo un monton a entender porque se cambiaba el next del head porque la verdad andaba enrredado y segundo: Rogelio, mas que el que cambiar el head y el tail es mas como si head y tail son el valor de una casilla entonces al igualarlo estos dos valores realmente son la misma casilla, por lo cual el modificar el uno o el otro realmente lo que haces es modificar lo que hay dentro de esa casilla, ya que no son objetos diferentes. No se si lo entendiste asi, pero me parecio que depronto era un poco mas claro verlo asi con casillas de cajas y cajas '^^
Omar Flores Grimontt
Josué Eduardo Apén Bal
¡Me salvaste bro! Me estaba partiendo la cabeza intentando entender eso, y medio tuve mis sospechas de que this.tail.next, afecta a this.head.next. Pero no lo pude corroborar. Gracias por tu aporte.
Luis Berenguer
Tu explicación me hizo entender, ésta clase me resultó complicada precisamente por eso. Porque al hacer this.tail = this.head estamos señalando el mismo espacio en memoria. Gracias crack.
Jorge Cruz Perez
Un poco de ayuda grafica, saludos :) Al inicio:
Jimmy Buriticá Londoño
Realmente tu primer ejemplo es al final y no al inicio.
Jorge Cruz Perez
Cierto, errorcillo, saludos :)
Juan Sebastián Agudelo
La logica es parecida al callback hell, es ir anidando punteros a direcciones en memoria de cada uno de los nuevos nodos, esto a final queda una estractura de cuando anidamos callbacks. . Para practicar la logica de programacion y que se les sea mas facil implementar en el codigo lo que se nos pide, yo les recomiendo hacer algo de pseudo codigo.
En lo personal yo hago un dibujo y escribo lo que deberia de hacer paso a paso. Esa es la manera en que practico mi logica. Te la recomiendo quizás a ti tambein te sirva como me sirve a mi
Andres Velasquez
Gracias Juan. Lo estoy practicando y es lo que más me ayuda a resolver la logica.
Agustina Corvo
Reto insert:
Agustina Corvo
Lo pensé con posiciones del 1 en adelante. 1 sería la primera posición de la lista.
Gabriel Rodriguez
TIP: Para comentar todas las líneas juntas:
simplemente aprietan Ctrl + K + C.
TIP: Para quitar el comment a todas las líneas juntas:
simplemente aprietan Ctrl + K + U. Saludos!!
Tomas Di Mauro
No lo conocía de esa forma, también se puede usar ctrl + } (para comentar y sacar el comentario es igual)
Andres Velasquez
Hey gracias! Lo habia buscado desde hace tiempo!!
Melisa Barrera
Si la singly list tiene muchos elementos, al agregar un nuevo head, todos se corren automáticamente un lugar hacia delante sin que tengamos que usar un for como con los arrays?
giovanni.sayago
Acá no se tienen posiciones fijas dentro de la lista sino cada nodo apunta al siguiente, para insertar un elemento al inicio simplemente debes decirle que va ser el nuevo head y que debe apuntar al head anterior. El resto de posiciones no van a cambiar porque van a seguir apuntando al mismo siguiente.
Karen Benites Segura
Sí, lo que sucede es lo siguiente:
Primero creas el nuevo nodo que será tu nuevo head dentro de poco.
Ese nuevo nodo es un objeto con dos propiedades: value y next. Inicialmente, next = null.
El HEAD actual es un objeto de objetos (objeto anidado), y contiene TODOS los nodos actuales.
¿Cómo entonces enlazas el head actual con el nuevo nodo?
Con la propiedad NEXT del nuevo nodo. Si al inicio newNode.next = null; basta con ponerle como valor de newNode.next a todooo el objeto HEAD actual (que a su vez ya contiene los demás nodos.)
newNode.next = this.head
Y así ya enlazaste los dos.
Pero falta un paso. Si lo dejas así nomás. no estás modificando nada de la linkedlist original, aún no has incluido el nuevo nodo dentro de la estructura de datos. Es como si simplemente crearas un nodo cualquiera patito y solo le pongas un valor X a su propiedad next.
Para hacer que el nuevo nodo de verdad sea la nueva cabeza de tu linked list, debes especificarlo.
"ahora quiero que mi head sea igual a este nuevo nodo que tengo (que ya está enlazado con todos los demás nodos)"
Y esto se hace así: this.head = newNode
Fernando Quinteros Gutierrez
Rigoberto Maldonado
Robinson Matias Aguilar Bascuñan
¿Cómo es posible que se agregue y no se sobreescriba tail cada vez que se llame a la function append?
Freddy J Marin L
De verdad le aplaudo a este profesor. De lo mejor que hay en platzi. Joya!
No dejen ir al gran Diego De Granda
Karen Paola Torres Archbold
Callback Hell puro.
Jefred Bedoya
Dejo la solución del reto anterior
append(value){ const newNode = new Node(value) this.tail.next = newNode //Apunto al siguiente nodo this.tail = newNode//Dejo la cola con el valor this.length++ }
Isaías Chávez Martínez
Si creen que es difícil hacerlo en js imaginense hacerlo en C por primera vez
giovanni.sayago
Hola comparto mis métodos:
append (value){ const newNode = new Node(value); this.tail.next = newNode; this.length++; this.tail = newNode; } prepend (value){ const newNode = new Node(value); newNode.next = this.head; this.length++; this.head = newNode; }
Kyb3r Cipher
Buena classe, me gustamucho esta estructura de dato. Interesante
Ana Rotela Cabrera
head -> -1 -> 0 -> 1 -> nullCopio y pego mi codigo pero se ve mal?
head -> -1 -> 0 -> 1 -> null
Alguien sabe como debo insertarlo?
Ya probe con inline code format y tambien insert block code
🗒 Aporte para la clase
Algo que me ayudo bastante a la hora de entender esta clase fue que estamos jugando bastante con la referencia de JavaScript. Recuerda mantener la idea de que no estamos guardando los valores de los objetos en sí, si no el lugar [referencia] de donde se encuentran en el memory heap.
El memory Heap es donde se guardan todos los objetos, debido a que los objetos necesitan una mayor cantidad de memoria a diferencia que los números, cadenas o boleanos, la desventaja es que el memory heap es lento por lo cual se necesita dar una ubicación de donde se está guardado. Si deseas saber más acerca de este tema puedes revisar este video creado por el profesor del curso de fundamentos de javascript
😉 Mi explicación del código según a lo que entendí
class MySinglyLinkedList { constructor(value) { // creamos el inicio de nuestro SinglyLinkedList this.head = { value, next: null, }; // Aqui sucede la magia ✨ // Todo lo que modifiquemos en los atributos de tail // se modificará en la estructura inicial // por la RERENCIA! this.tail = this.head; this.length = 1; } append(value) { // aquí estamos creando un nuevo nodo const newNode = new Node(value); // Como mencionamos anteriormente // si modificamos la cola por la REFERENCIA // se modificará la estructura inicial! 🖊 this.tail.next = newNode; // Pero aun tail sigue apuntando a la CABEZA // de la estructura inicial entonces es momento // de apuntar al nuevo nodo creado para que posteriormente // podamos agregar más nodos! 🚀 this.tail = newNode; // Finalmente aumentamos el tamaño definido de // nuestra estructura 👨🔧 this.length++; return this; }
💚 Cualquier correción o comentario es bienvenido!
Gracias, tu aporte me ayudó a entenderlo, luego hice mis propios apuntes, explicado a como entendí, por si les interesa, si hay algún error diganme por favor :)
class ListNode { constructor(value) { this.value = value; this.next = null; } } class SinglyLinkedList { constructor(value) { this.head = { value: value, next: null, }; //tail y head apuntan a la misma direccion de memoria // y si cambia UNA PROPIEDAD de uno, cambiará en el otro this.tail = this.head; this.length = 1; } //insertar al final //Esto funciona ya que en el contructor hay una referencia //cambiamos UNA PROPIEDAD del tail entonces también cambia en el head append(value) { const newNode = new ListNode(value); //creamos nueva referencia this.tail.next = newNode; //el next del head y el next del tail es el mismo this.tail = newNode; //tail y el next de head tienen la misma referencia this.length++; return this; /* Entonces ahora tail y ese nodo que se agregó el next del head es el next de ese nodo que se agregó Ambos next estan referenciados, COMO AL INICIO entonces cuando creemos otro nodo simplemente se repetirá el proceso */ } } let singlyLinkedList = new SinglyLinkedList(1);
Creo que para esta clase es importante entender también que cuando generamos un objeto en JS y luego igualamos otra variable a la variable anterior lo que hacemos es que apuntamos desde las dos variables al mismo espacio en memoria, por eso cuando decimos:
this.head = new Node(value) this.tail = this.head
Cada vez que hagamos un cambio en this.tail ese cambio también va a afectar a this.head, por eso en el método append, cuando le decimos:
this.tail.next = newNode
A su vez también cambiamos el valor this.head.next, luego hacemos que this.tail apunte al espacio en memoria de newNode diciéndole:
this.tail = newNode
La próxima vez que cambiemos this.tail ya no va a afectar a this.head. Gracias a esto es que podemos aplicar los métodos append y prepend de esta manera, esto lo podemos probar haciendo en el constructor de SinglyLinkedList lo siguiente:
this.head = { value: value, next: null } this.tail = {...this.head}
De esa manera this.tail ya no estará apuntando al espacio en memoria que ocupa this.head sino que pasará a ocupar uno nuevo, y los cambios que se hagan en this.tail no afectaran a this.head por ende el método de append la primera vez que se llama no hará que mute this.head. Esto es un problema porque no es el comportamiento que queremos, pero es importante que entendamos que no siempre la mutabilidad en JS es mala (aunque la querramos evitar en la mayoría de los casos) y qué podemos sacarle provecho sabiéndola utilizar. La otra opción es evitar que los objetos muten y tener control sobre lo que ocurre tanto en this.tail como en this.head.
👩💻👨💻 Código de la clase
// 1 --> 2 --> 3 --> 4 --> 5 --> null // let singlyLinkedLis = { // head: { // value: 1, // next: { // value: 2, // next: { // value: 3, // next: { // value: 4, // next: null // } // } // } // } // } class Node { constructor(value) { this.value = value; this.next = null; } } class MySinglyLinkedList { constructor(value) { this.head = { value, next: null } this.tail = this.head; this.length = 1; } append(value) { const newNode = new Node(value); this.tail.next = newNode; this.tail = newNode; this.length++; return this; } prepend(value) { const newNode = new Node(value); newNode.next = this.head; this.head = newNode; this.length++; return this; } } let myLikedList = new MySinglyLinkedList(1); console.log(myLikedList); console.log(myLikedList.append(2)); console.log(myLikedList.prepend(0));
buen dia, cuando se agrega un nuevo nodo en la lista con el metodo insert con un solo parametro, se genera un undefine como lo de la imagen.
insert(index, value) { //add a node "outside" the list (=> invalid) if(index < 0 || index > this.length) { return null; } else if(index === 0) { //add a node to the beginning of the list return this.prepend(value); } else if(index === this.length) { //>= //add a node to the end of the list return this.append(value) } else { const newNode = new Node(value); const firstPointer = this.getTheIndex(index - 1); const holdingPointer = firstPointer.next; firstPointer.next = newNode; newNode.next = holdingPointer; this.length++; return this; } } getTheIndex(index) { let counter = 0; let currentNode = this.head; while(counter !== index) { currentNode = currentNode.next; counter++; } return currentNode; }