No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Agregar nodos a la lista

17/29
Recursos

Aportes 75

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

馃棐 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!

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.

Un poco de ayuda grafica, saludos 馃槂
Al inicio:

Intermedio :

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.

  • Escribir literal el paso a paso
  • dibujar ayuda tambien
  • la tecnica del patito de hule suele funcionar.

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

Reto insert:

Es simple, de hecho me recuerda mucho a los callbacks hell jajaja, simplemente se trata de crear un nuevo nodo y meterlo dentro del next del nodo que est谩 actualmente como la cola.
.
Y para la cabeza, lo 煤nico que hicimos fue, agarrar la cabeza actual, que ya conten铆a toda nuestra lista de nodos hijos, y meterla en una nueva cabeza, de esa forma pudimos hacer un prepend ^^

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!!

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;
  }

De verdad le aplaudo a este profesor. De lo mejor que hay en platzi. Joya!

No dejen ir al gran Diego De Granda

Callback Hell puro.

馃懇鈥嶐煉火煈ㄢ嶐煉 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));

class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}

class MySinglyLinkedList {
constructor(value) {
this.head = {
value: 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 myLinkedList = new MySinglyLinkedList(1);

aqui con micho esfuerzo hice un metodo para agregar un nodo en cualquier posicion indicada

    add (index,value) {
        const newNode = new Node(value);
        let actualNode = this.head
        let previusNode = this.head
        for (let i = 1; i < index; i++) {
            if (i == index - 1) {
                previusNode = actualNode
            }
            
            if (actualNode.next) {
                actualNode = actualNode.next
            } else {
                return
            }
        }
        
        newNode.next = actualNode
        previusNode.next = newNode
        this.length++
        return this;
    }

Me record贸 a la clase de punteros en C, en el 2009. No solo variables sino espacios de memoria.
馃く馃く

La clase es muy clara pero considero que el profesor debi贸 haber echo un peque帽o recordatorio de que el tail apunta a la referencia del 煤ltimo valor del linkedList, esta es la raz贸n por que al reasignar el next del tail se modifica el valor en el linkedList.

Sin esto claro, el c贸digo funciona bien pero no queda claro porque y creo que puede confundir bastante, pero el tema de la clase es super claro y se entiende perfecto.

Para cualquiera que tenga esta duda y quiera entender en detalle como funcionan los valores por referencia les dejo este articulo que deja super claro el tema.

https://www.javascripttutorial.net/javascript-primitive-vs-reference-values/

addNode(value){
    let node = new Node(value);
    this.tail.next=node;
    this.tail = node;
  }

Creo que aqui se debio hacer mas mencion a la diferencia entre pasar valores por Referencia y Valor, ya que es la base para entender los metodos de Append y prepend

Cuando usamos palabras reservadas o metodos, entiendo que todo nace del s煤per prototipo, pero como es que esta construido el super prototipo. Estamos construyendo estas estructuras gracias a la capa de abstracci贸n anterior pero tarde o temprano llegamos al super prototype, 驴Como esta construido el super prototype?

Para agregar en cualquier lado:

insert(value,pos){
        if(pos == 0){
            this.prepend(value);
        }else if(pos >= this.length - 1){
            this.append(value);
        }else{
            const node = new Node(value);
            const datatoInsert = this.explore(this.head,pos);
            node.next = datatoInsert.next;
            datatoInsert.next = node;
            this.length++;
        }
    }

    explore(nodeActual,limit){
        if(limit == 0){
            return nodeActual;
        }else{
            return this.explore(nodeActual.next,limit - 1);
        }
    }

El prepend:

prepend(value){
        const node = new Node(value);
        node.next = this.head;
        this.head = node;
        this.length++;
        
    }

Hice este metodo para imprimir los datos en formato de linked list. Una ayuda para entender mejor.

print() {
    let result = "";
    let currentNode = this.head;
    while (currentNode) {
      if (!currentNode.next) {
        result += ` ${currentNode.data}`;
      } else {
        result += ` ${currentNode.data} -->`;
      }
      currentNode = currentNode.next;
    }
    return result;
  }

Yo hice el Prepend un poco diferente pero funciona igual:

	prepend(value) {
		const body = this.head;
		const newNode = new Nodo(value);
		this.head = newNode;
		this.head.next = body;
		this.length++;

		return this;
	}

mi ejercicio esta en python pero creo que para las personas que esten haciendo este curso por la forma que crea las estructuras de datos le servira o vera otra manera de realizarlo.

<
class Node:
    
    def __init__(self,data) -> None:
        self.data = data
        self.next = None


class LinkendList:

    def __init__(self) -> None:
        self.head = None
        self.tail = self.head
        self.size = 0
    
    
    def insert(self,data):
        """insert method
            This method allow us add a new item at the end of the LinkedList.

        Args:
            data (_type_): value that will be take the next node to add.
        """
        
        new_item = Node(data)

        if not self.head:

            self.head = new_item
            self.tail = self.head
        elif self.size == 1:

            self.tail = new_item
            self.head.next = self.tail          

        else:
            current = self.tail
            current.next = new_item
            self.tail = current.next
        



new_linkedList = LinkendList()
new_linkedList.insert(23)
new_linkedList.insert(40)
new_linkedList.insert(20)

current = new_linkedList.head
while current :
    print(current.data,end=' -> ')
    current = current.next> 
class MyNode {
  value: String|Number|Array<any>
  next: any
  constructor(value: String|Number|Array<any>) {
    this.value = value
    this.next = null
  }
}

// Singly linked list
class MyLinkList {
  public head: MyNode
  public tail: MyNode
  public length: number
  constructor(value: String|Number|Array<any>) {
    this.head = new MyNode(value)
    this.tail = this.head
    this.length = 1;
  }

  append(value: String|Number|Array<any>) {
    const newNode = new MyNode(value)
    this.tail.next = newNode
    this.tail = newNode
    this.length++
    return this
  }

  preppend(value: String|Number|Array<any>) {
    const newNode = new MyNode(value)
    newNode.next = this.head
    this.head = newNode
    this.length++
    return this
  }
}

Aproveche el curso para escribir mis primeras l铆neas de TypeScript lo cual recomiendo, lo hace ligeramente m谩s retador mientras aprendes algo extra. URL TypeScript playground y la documentaci贸n de TypeScript

Es excelente, es la misma logica que se usa para el patron de una cadena de responzabilidad. https://refactoring.guru/es/design-patterns/chain-of-responsibility

As铆 lo hice yo

newNode(value){
        this.tail.next = new Node(value);
        this.tail = this.tail.next;
        this.length++;
    }

Mi solucion a los retos con la implementacion de un metodo que imprime a la singly linked list como si fuera un array normal

class Node {
  constructor(value, next = null) {
    this.value = value;
    this.next = next;
  }
}

class SinglyLinkedList {
  constructor(value) {
    this.head = new Node(value);
    this.tail = this.head;
    this.length = 1;
  }
  append(value) {
    const newNode = new Node(value);
    this.tail.next = newNode;
    this.tail = newNode;
    this.length++;
  }
  prepend(value) {
    this.head = new Node(value, this.head);
    this.length++;
  }
  print() {
    let current = this.head;
    let linkedList = [];
    while (current != null) {
      linkedList.push(current.value);
      current = current.next;
    }
    console.log(linkedList);
  }
}

Cree el m茅todo a trav茅s de una funci贸n recursiva

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class SinglyLinkedList {
  constructor(value) {
    this.head = { value, next: null };
    this.tail = new Node(value);
    this.length = 1;
  }

  _assignNext(instance, newNode) {
    if (instance.next === null) {
      instance.next = newNode;
      return;
    }
    this._assignNext(instance.next, newNode);
  }

  append(value) {
    this._assignNext(this.head, new Node(value));
    this.length++;
  }
}

const pageNavigator = new SinglyLinkedList("htps://platzi.com");
console.log(pageNavigator.length, pageNavigator.head);

pageNavigator.append("htps://digital.dev.greatminds.dev/");
console.log(pageNavigator.length, pageNavigator.head);

pageNavigator.append("htp://localhost:3000/");
console.log(pageNavigator.length, pageNavigator.head);

Este es mi aporte a la comunidad

<code> 
function Nodo(value){
    this.value = value,
    this.next = null
}

class SingleLinkedList {
    constructor(value) {
        this.head = {
        value : value,
        next : null
    }
    this.tail = this.head
    this.length = 1
    }
****}

Me acuerdo cuando en la Universidad alcance a ver este tema pero con Java, la verdad esto de las listas es muy divertido, ll谩menme loco jajajajja

Mi soluci贸n al insertar implementado en TypeScript:

  insert(value: T, position: number): void {
    if (position >= this._length) return this.append(value);
    if (position <= 0) return this.prepend(value);

    const node = new Node(value);
    let current = this.head;
    let previous = this.head;
    for (let i = 0; i < position; i++) {
      previous = current;
      current = current!.next;
    }
    previous!.next = node;
    node.next = current;
    this._length++;
  }

Esta es la alternativa usando recursividad (es menos 贸ptima que la del profe porque 茅l usa el tail como acceso directo y no tiene que recorrer la estructura completa) pero la recursividad es algo que se pide mucho en pruebas t茅cnicas para Amazon, google, etc as铆 que nunca est谩 de mas practicarla

append(value,current){
        //console.log(!current)
        if(!current){
            current=this.head
        }
        if(current.next==null){
            let nodo=new Nodo(value)
            current.next=nodo
            this.tail=nodo
        }else{
            this.append(value,current.next)
        }
    }

Les comparto mi soluci贸n a la implementaci贸n del m茅todo insert(value, position). Criterios de aceptaci贸n que defin铆 para una lista de N nodos:

  • podr谩 insertar al inicio y al final de la lista
  • position debe ser > 0 y <= this.length +1
  • si position = 1 entonces hace un prepend(value)
  • si position = this.length +1 entonces hace un append(value)
  • debe poder insertar un nodo en cualquier posici贸n dentro de la lista.
    insert(value, position) {
        if(position > 0 && position <= this.length +1) {
            if(position == 1) {
                this.prepend(value);
                return this;
            }
            if(position == this.length +1) {
                this.append(value);
                return this;
            }
            let newNode = new MyNode(value);
            let nextNode = this.head;
                for(let i = 1; i < position -1; i++) {
                nextNode = nextNode.next;
            }
            let tempNode = nextNode.next;
            nextNode.next = newNode;
            newNode.next = tempNode;
            this.length++;
            return this;
        }
        return undefined;
    }
<code> 
    public getNode(indexValue : number) : Node | null{
        let currentNode : Node | null = this.head.next
        if (currentNode){
            while(currentNode.value !== indexValue){
                let nextNode : Node | null = currentNode.next
                if (nextNode){
                    currentNode = nextNode
                }else{
                    return null
                }
            }
        }else{
            return null
        }
        return currentNode
    }
    public insertNodeAfter(previousNodeValue : number, value : number) : void{
        let newNode : Node = new Node(value)
        let previousNode : Node | null = this.getNode(previousNodeValue)
        if (previousNode){
            let nodeToReplace : Node | null = previousNode.next
            previousNode.next = newNode
            newNode.next = nodeToReplace
            this.length = this.length + 1            
        }
    }

<code>


esto me funciona

My code of append function

   append(value){
     if (this.length = 1) {
       this.head.next = new Node(value);
       this.tail = this.head.next;
       this.length++;
      } else if (this.length > 1) {
        let current = this.head;
        while ( current.next ) {
          current = current.next;
        }
        current.next = new Node(value)
        this.tail = current.next;
        this.length++;
      }

Despues de un buen rato consegui resolver el reto
Ojo: Este codigo va dentro de la clase de mySingleLinkedList

insert(value)
  {
    if(this.length > 1)
    {
      const div = Math.round(this.length/2)
      const newNode = new Node(value)
      this.view(this.head,div,newNode)
      return this
    }
    this.append(value)
  }

// No sabia que nombre ponerle a esta funcion y como la inicie view por esa era su funcion antes
  view(node, veces, newNode)
  {
    veces--
    if(veces === 0)
    {
      newNode.next = node.next
      node.next = newNode
      this.length++
      this.view2(this.head,1)
      return this
    }
  }

As铆 lo hice yo, ahora a ver como se hace

insert(value, pos){
    const newNode = new Node(value);
    let tail;
    let nodes = [this.head];
    if(pos >= 0 && pos <= this.length - 1){
        for(let i = 0; i <= pos; i++){
            if(nodes[nodes.length - 1].next){
                if(i == pos - 1){
                    tail = nodes[nodes.length - 1].next;
                    nodes[nodes.length - 1].next = newNode;
                }
                nodes.push(nodes[nodes.length - 1].next);
            }else{
                nodes[nodes.length - 1].next = tail;
                this.length++;
                return this.head;
            }
        }
    }else{
        if(pos <= this.length){
            this.prepend(newNode);
        }else{
            this.append(newNode);
        }
    }
}

As铆 implemente yo los metodos append y prepend:


class Node  {
    constructor(value){
        this.value = value;
        this.next = null
    }
}

class MySinglyLinkedList  {
    constructor(value) {
        this.head = {
            value: value,
            next: null
        }
        this.tail = this.head;
        this.length = 1;
    }

    append(value){
        let newNode = new Node(value)

        let lastNode = this.head;
        
        for(let i = 1; i  < this.length; i++){
            lastNode = lastNode.next;
        }

        lastNode.next = newNode;

        this.length++;
        this.tail = newNode;

        return this;
    }

    prepend(value) {
        let newNode = new Node(value);

        newNode.next = this.head

        this.head = newNode;

        this.length++;

        return this;
    }
}

Este fue el reto de la anterior clase as铆 fue que lo hice

class Node {
  constructor(value) {
    this.value = value
    this.next = null
  }
};

class mySinglyLinkedList {
  constructor(value) {
    this.head = {
      value: value,
      next: null
    }
    this.tail = this.head;
    this.length = 1;
  }
  push(value) {
    this.tail.next = new Node(value);
    this.tail = this.tail.next
    this.length++
    return this.head;
  }
};


const myLinkedList = new mySinglyLinkedList(1);

myLinkedList.push(2);
myLinkedList.push(5);
myLinkedList.push(4);
myLinkedList.push(5); 
myLinkedList.push(3);
myLinkedList.push(8);

myLinkedList.length;

Mi soluci贸n para agregar un elemento en un 铆ndice cualquiera:

 insert( index, value ) {
        if( index < 0 ) return;
        if( index >= this.length-1 )return this.append(value);
        if (index === 0) return this.prepend(value);
            
        const newNode = new Node( value );
        let nodeAt = this.head;
        for ( let i = 1 ; i <= this.length ; i++) {
            if(i === index){
                newNode.next = nodeAt.next;
                nodeAt.next = newNode;
                this.length++
                return this;
            }else{
                nodeAt = nodeAt.next
            }
        }
        return this
    }

Git hub copilot lo hizo por mi, anyway era la l贸gica que tenia en mente desarrollar 馃槃

    constructor(value) {
        this.head = new Node(value);

        this.tail = this.head;
        this.length = 1;
    }
    append(value) {
        const newNode = new Node(value);
        this.tail.next = newNode;
        this.tail = newNode;
        this.length++;
    }


M茅todo append (position es diferente a index, dado que comienza desde 1):

    insert (value, position) {
        const newNode = new Node(value);
        let prevNode;
        let node = this.head;
        let nextNode;

        for (let i = 1; i < position; i++) {
            if (i == position - 1) {
                prevNode = node;
                nextNode = node.next;
            }
            node = node.next;
        }

        prevNode.next = newNode;
        newNode.next = nextNode;

        this.lenght++;

        return this;
    }

Mi soluci贸n al reto 馃槃:

class node {
    constructor(value) {
        this.value = value;
        this.next = null;
    }
}

class singleLinkedList {
    constructor(value) {
        this.head = {
            value : value,
            next : null
        }

        this.tail = this.head;

        this.length = 1;
    }

    append(newValue) {
        this.tail.next = new node(newValue);
        this.tail = this.tail.next;
        this.length+=1;
    }

}

let myLinkedList = new singleLinkedList(10);

Aqu铆 les comparto mi metodo insert

insert(value, numInsertNode) {
        const node = new Node(value);
        let nodeSelected = this.head;
        if(numInsertNode > this.length) {
            numInsertNode = this.length;
        }
        for(let i = 0; i < this.length; i++) {
            if(i === numInsertNode){
                node.next = nodeSelected;
            }
            nodeSelected = nodeSelected.next;
        }

        let insertNode = this.head;
        for(let i = 0; i <= numInsertNode; i++) {
            if(i === numInsertNode -1){
                insertNode.next = node;
                break;
            }
            insertNode = insertNode.next;
        }
        if(this.length === numInsertNode){
            this.tail = node;
        }

        this.length++;
        return this;
    }
class Node {
  constructor(value){
    this.value = value;
    this.next = null;
  }
}


class MySinglyLinKedList {
  //Se genera con un valor 
  constructor(value){
    this.head = {
      value: value,
      next: null,
    }
    this.tail = this.head;
    this.length = 1;
  }

  checknode(node){
    if (!node.next){
      return node;
    }
    return this.checknode(node.next);
  }

  //Problema es que solo actualiza ese primer next 
  //Tenemos que crear otro next
  append(value){
    //Recibir el valor del nodo
    let current = new Node(value);
    //Creamos que vaya al siguiente next creado
    const lastNode = this.checknode(this.head);
    lastNode.next = current
    //Cambiamos el valor next del head
    this.tail = current;
    this.length++;
    return this.head;
  }

}

let myLinkedList = new MySinglyLinKedList(1);
console.log(myLinkedList.append(2))
console.log(myLinkedList.append(3))

Mi m茅todo append()

append(value){
    const newNode = new Node(value);
        
    this.tail.next = newNode;
    this.tail = newNode;
    
    this.length++;
}

Convierte tu LinkedList a un array

toArray() {
    const arr = [];
    let n = this.head;
    do {
      arr.push(n.value);
      n = n.next;
    } while (n);
    return arr;
  }
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedL {
  constructor(value) {
    this.head = {
      value,
      next: null,
    };

    this.tail = this.head;
    this.len = 1;
  }

  append(val) {
    const n = new Node(val);
    this.tail.next = n;
    this.tail = n;
    this.len++;
  }
}

const l = new LinkedL(1);
for (let i = 0; i < 14; i++) {
  l.append(i);
}
console.log(l);

Les comparto el m茅todo toString para que puedan imprimir los valores de la SingleLinkedList de manera m谩s visual:

toString() {
  let current = this.head
  let linkedList = `${[current.value]} -> `

  while(current.next) {
    current = current.next
    linkedList += `${[current.value]} -> `
  }

  linkedList += 'null'

  return linkedList
}

metodo append con explicacion

  append(value){
    this.length++
    // se crea un nodo, unico e irrepetible. solo referenciable.
    const node = new Node(value)
    
    /* la primera vez:
    this.tail.next apunta a this.head.next por lo que los dos apuntan hacia node
    entonces: 
      this.head == 
      this.tail == 
      {value: 1, next: node} ==
      {value: 1, next: {value: 2, next: null}}
    vv
    en la siguente linea this.tail ahora apunta unicamenxd7 te al node al que se asigno a head. 
    entonces:
      this.tail !== this.tail
      this.tail == node
      this.head == {value: 1, next: node}
      this.head == {value: 1, next: this.tail}
      
    por lo que tail termina apuntando a la ultima posicion de head, y en las siguientes veces que sea convocada la funcion los cambios de tail seran reflejados la ultima posicion de head
    */
    this.tail.next = node 
    this.tail = node
    // while(curr.next !== null) curr = curr.next
    // curr.next = node
  }
  append(value){
    this.length++
    let curr = this.head
    const node = new Node(value)
    while(curr.next !== null) curr = curr.next
    curr.next = node
  }

Creo que as铆 no era JAJAJAJAJAJ.

//Asi es como yo hize el mecanismo para agregar un nuevo nodo, sin embargo creo que el del profesor va a estar mejor haha.
    append(value){
        const linkNode = new NodeLink(value);
        this.recorrer(this.head, linkNode); // Este metodo nos va a servir para recorrer el objeto en todas sus profundidades
    }
    recorrer(obj, node) { // Recibe dos parametros, el objeto que queremos que recorra y el nodo que queremos que agregue
        for (let properties in obj) { // properties representa cada uno de los index/keys que tiene el objeto
            if (this.isObject(obj[properties])) { // Verifica si el value de la key que esta recorriendo es un objeto por el metodo isObject() definida abajo
                this.recorrer(obj[properties], node); // Si alguno de los values del objeto es otro objeto se va a llamar a ella misma, usando recursividad
            } else if (obj[properties] === null ) { // Si no, entonces miremos si esos values tiene null, que es el value del next
                obj[properties] = node; // Si lo encuentra entonces vas a asignar a ese value el nodo que le pasamos como parametro
                this.tail = node; // Lo va a volver la cola de la linked list
                this.length++; // Vamos a aumentar el registro
                return this.head; // Y vamos a retornar this.head
            }
        }
    }
    isObject(obj) {
        return Object.prototype.toString.call(obj) === '[object Object]'; // Nos metemos en el prototype de toString() para a帽adirle un this que sea el objeto que queremos verificar si es un objeto, si ese string sale a dicha representacion, devuelve true
    }

Inicia explicaci贸n

Yo lo hice un poco diferente, dejo el metodo prepend y el codigo completo explicado como tambien el resultado

// Metodo para agregar un nodo al inicio.
// Este metodo recibira el valor que tendra el nodo.
preppend(value) {
    // Creamos nuestro nuevo nodo, este recibira el valor que contendra y el valor de next,
    // Que en este caso sera this.head, esto quiere decir que el valor que este en este momento en el head de nuestra linkedList
    // Sera el siguiente del nuevo nodo
    const newNode = new Node(value, this.head);

    //Validamos si existe un nodo en el head, es decir, si nuestra LinkedList No esta Vacia
    if (!this.head) {
      // Si no existe un valor en el head quiere decir que nuestra linkedList esta vacia
      // Entonces el nodo que estamos agregando es el primer nodo por lo cual sera el head y el tail a la vez
      this.tail = newNode;
    }

    // Si no se cumple la validacion anterior quiere decir que nuestra linkedList tiene elementos.
    // Entonces al head tenemos que apuntarlo al nuevo nodo
    this.head = newNode;
    // Por ultimo Incrementamos en 1 la longitud de la LinkedList
    this.length++
  }

c贸digo final

// creaci贸n del Nodo, que recibe como parametro las propiedades que tendra dicho nodo
class Node {
  // Como sabemos en una SinglyLinkedList los nodos solo tendran dos valores
  constructor(value,next) {
    this.value = value; //value, que sera el dato que contendra el nodo
    this.next = next; // next, que har谩 referencia al siguiente nodo
  }
}

// Creacion de la clase SinglyLinkedList que contendra toda la logica de nuestra LinkedList
class SinglyLinkedList {
  // Esta clase tendra como propiedades el head y el tail el cual estaran inicializados en null
  // esto quiere decir que empezaremos con una LinkedList Vacia y por ende su longitud sera 0
  constructor(){
    this.head = null;
    this.tail = null;
    this.length = 0;
  }

  // implementacion del metodo append, este agregara un nodo al final de la LinkedList
  // y recibira como parametro el valor que contendra el nodo que se insertara
  append(value) {
    const newNode = new Node(value, null);

    // hacemos una validacion si existe algun nodo al final de la LinkedList.
    if(this.tail) {
      // Si existe un nodo al final, entonces decimos que su next sera el nuevo nodo que creamos
      this.tail.next = newNode;
    } else {
      // Si no existe quiere decir que nuestra LinkedList esta vacia.
      // Esto quiere decir que el Nodo que esta agregando es el primero
      // Como es el primero entonces ese nodo sera el head y el tail a la vez.
      // por lo cual al head le asignamos el nuevo nodo
      this.head = newNode;
    }
    // Colocamos al nodo creado como el tail 
    this.tail = newNode;
    // Incrementamos en 1 la longitud de nuestra lista
    this.length ++;
  }
  
  // Metodo para agregar un nodo al inicio.
  // Este metodo recibira el valor que tendra el nodo.
  preppend(value) {
    const newNode = new Node(value, this.head);

    if (!this.head) {
      this.tail = newNode;
    }
    
    this.head = newNode;
    this.length++
  }
}

Soluci贸n

Algo as铆 qued贸:

class MySinglyLinkedList {
  constructor(value) {
    this.head = {
      value: value,
      next: null
    };
    this.tail = this.head;

    this.length = 1;
  }

  append(value) {
    let currentNode = this.head;
    let newNode = new Node(value);
    this.head = newNode;
    this.head.next = currentNode;
    if (currentNode.next == null) {
      this.tail = currentNode;
    }
    this.length++;
  }
}

I implemented the append method with a recursive method so I didn鈥檛 have to use the tail prop. The list and trees can be handled with recursion.

append(value){
    
    
      let newNode = this.searchTail(this.head, value);
      this.tail = newNode;
      this.length++;
  }

  searchTail(node, value){

    if(!node.next){
      const newNode = new Node(value);
      node.next = newNode;
      return newNode;
    }else{
      return this.searchTail(node.next, value)
    }
  }


Reto terminado

    insert(index,value){
        const newNode = new Node(value);
        let target = this.head;
        let slice = undefined;
        for (let i = 1; i < index; i++) {
            target = target.next;
        }
        slice = target.next;
        target.next = newNode;
        target.next.next = slice;
        return console.log(this.head);
    }

asi fue mi soluci贸n:

append(value){
        const newNode = new Node(value);
        this.recursiveMethod(this.head,newNode)
        this.length ++;
        return this.head;
    }
    recursiveMethod(obj, newNode){
        if(obj.next === null){
            return obj.next = newNode;
        }
        for(let prop in obj){
            if(prop === 'next')
            {
                this.recursiveMethod(obj[prop],newNode);
            }
        }
    }
class myNode {
  constructor(value) {
    this.data = value;
    this.next = null;
  }
}

class MySinglyLinkedList {
  constructor() {
    this.head = null;
    this.tail = this.head;
    this.length = 0;
  }

  append(value) {
    const newNode = new myNode(value);
    if (this.head === null) {
      this.head = newNode;
    } else {
      this.next = newNode;
    }
    this.tail = newNode;
    this.length++;

    return this;
  }
}

let mySinglyLinkedList = new MySinglyLinkedList();

antes de seguir con el curso aca dejo mis metodos para comparar despues

append(value) {
    this.tail.next = new Node(value)
    this.tail = this.tail.next
    this.length++

    return this.tail
  }

  prepend(value) {
    let newHead = new Node(value)
    newHead.next = this.head
    this.head = newHead
    this.length++
    
    return this.head
  }

re mal amigo 馃槀

    insert(value, position){

        for(let i=0; i<this.length; i++){
            if(Object.keys(this.head.next) < 1 ){
                if(this.head.value === position){
                    this.prepend(value)
                    this.length ++;

                }
            }
        }
        return this
    }

Orale! Vamos a intentarlo carnales

Aqui les dejo otra forma mas simplificada de hacer el prepend (Ecma)

    prepend(value) {
        let newNode = new node(value)
        this.head = {...newNode, next: this.head}
        this.length ++;
        return this;
    }

ejercicio del append resulto antes de ver el video

class Nodo {
  constructor(value) {
    this.value = value;
    this.next = null;
  }

  getNodo(){
      return{
          value:this.value,
          next: this.next,
      }
  }
}

class MySinglyLinkedList {
    
    constructor(value) {
        this.head = {
        value: value,
        next: null,
        };
        this.tail = this.head;

        this.length = 1;
    }

    append(value){
        this.tail = new Nodo(value).getNodo();
        this.length++;
        this.head.next = this.tail;
        return this.head;
    }
}

Estoy en el minuto 8:58 espero que esta solucion sea la correcta 馃槃

MY NOTES FROM NODES TO THE LIST 馃槃

class Node{

  constructor(value){

    this.value = value;
    this.next  = null;
  }
}

class MySinglyLinkedList{

  constructor(value){

    this.head = {
      value: value,
      next: null,


    }
    this.tail = this.head;

    this.length = 1;
  }
  append(value){
    //generamos una constante en la cual vamos a generar un nuevo
      //Nodo que se va a colocar en la cola de nuestra lista
        //Hacemos una instancia de la clase que crea nuestros nodos
    const newNode = new Node(value);
    //Le asignamos a la cola el nuevo nodo pero para la fila el ultimo nodo
      //Que habia en la fila sigue siendo la fila
    this.tail.next = newNode;

    //Luego le indicamos a la fila que el ultimo nodo es el que creamos
    this.tail = newNode;

    //Incrementamos la logintud de nuestra lista
    this.length++;

    return this;



  }

  prepend(){

    const newNode = new Node(value);

    newNode.next = this.head;

    this.head = newNode;

    this.length++;

    return this;





  }

}

let myLinkedList = new MySinglyLinkedList(1);

mi humilde aporte
![](

insert(nodeNumber, value){
    // 1 2 3 4 5
    if(nodeNumber > this.length){
      return undefined;
    }else if(nodeNumber === 0){
      this.prepend(value);
      return this;
    }else if(nodeNumber === this.length -1){
      this.append(value);
      return this;
    }
    
    const newNode = new Node(value);
    let pointer = this.head;
    for(let i = 0; i < (nodeNumber - 1); i++){
      pointer = pointer.next;
    }
    newNode.next = pointer.next;
    pointer.next = newNode;
    this.length++;
    return this;
  }

Pr谩cticamente el ejemplo que se genera en esta clase juega con las referencias por eso al momento de modificar el head tail se ve afectado

Mi soluci贸n:

class Node {
    constructor (value) {
        this.value = value;
        this.next = null;
    }
}

class MySinglyLinkedList {
    constructor(value) {
        this.head = new Node(value);
        this.tail = this.head;
        this.length = 1;
    }
    append(value) {
        const newNode = new Node(value);
        this.tail.next = newNode;
        this.tail = newNode;
        this.length++;
    }
}

M茅todo insert

insert(value, index){
        if(index<this.length){
            let currentNode = this.head;
            let before;
            for(let i=0;i<this.length;i++){
                if(i===index-1){
                    let node = new Node(value);
                    node.next = currentNode;
                    before.next = node;
                    this.length++;
                    return this;
                }
                before = currentNode;
                currentNode = currentNode.next;
            }
        }else{
            return "overflow"
        }
    }

Mi insert para el reto 馃槉

insert(value, position) {
        if(position <= this.length) {
            if (position === 0) this.prepend(value)
            else if (position === (this.length)) this.append(value)
            else {
                let aux = this.head
                let newNodo = new Nodo(value)
                for(let i = 1; i < position; i++){
                    aux = aux.next
                }
                newNodo.next = aux.next
                aux.next= newNodo 
                this.length++
            }
        }
    }```

Ah铆 va la implementaci贸n del m茅todo insert:

    insert ( value, position ){

        if( position === 0)
            this.prepend( value )
        else if( position === this.length )
            this.append( value )
        else {

            const insertedNode = new Node( value )
            
            let previousNode = this.head
            
            for( let i=1; i < position; i++){
                previousNode = previousNode.next
            }
            
            let nextNode = previousNode.next
            
            insertedNode.next = nextNode
            previousNode.next = insertedNode
            
        }
        
        this.length += 1
        return this
    }

Soluci贸n al reto

insert(value, index) {
    if (index === 0) {
      this.prepend(value);
      return;
    }
    if (index === this.length) {
      this.append(value);
      return;
    }
    
    const newNode = new Node(value);
    let auxNode = this.head;
    for (let i = 0; i < index-1; i++) {
      auxNode = auxNode.next;
    }
    newNode.next = auxNode.next;
    auxNode.next = newNode;
    this.length++;
    return this;
  }