Files

5.0 KiB

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
587d8251367417b2b2512c63 Remover elementos de uma lista encadeada 1 301712 remove-elements-from-a-linked-list

--description--

O próximo método importante que qualquer implementação de uma lista encadeada precisará é de um método remove. Este método deve receber como argumento o elemento que queremos remover, e, em seguida, procurar na lista para encontrar e remover o nó que contém esse elemento.

Sempre que removermos um nó de uma lista encadeada, é importante que não deixemos o resto da lista órfã ao fazer isso. Lembre-se de que todos os pontos de propriedade next dos nós apontam para o nó que os segue na lista. Se estivermos removendo o elemento do meio, digamos, vamos precisar ter certeza de que temos uma conexão com a propriedade next do nó anterior daquele elemento para a propriedade next do elemento do meio (que é o próximo nó na lista!)

Isso pode parecer muito confuso, então vamos voltar ao exemplo da fila de dançarinos de conga para que tenhamos um bom modelo conceitual. Imagine-se em uma fila de dançarinos de conga e que a pessoa diretamente à sua frente saia da fila. A pessoa que acabou de deixar a fila já não tem as mãos sobre ninguém da fila - e você já não tem as mãos sobre a pessoa que saiu. Você dá um passo para a frente e coloca as mãos na próxima pessoa que vê.

Se o elemento que queremos remover for o elemento head, reatribuímos a propriedade head para o segundo nó da lista encadeada.

--instructions--

Escreva um método remove que pegue um elemento e o remova da lista encadeada.

Observação: o length da lista deve diminuir em um sempre que um elemento for removido da lista encadeada.

--hints--

A classe LinkedList deve ter o método remove.

assert(
  (function () {
    var test = new LinkedList();
    return typeof test.remove === 'function';
  })()
);

O método remove deve reatribuir head ao segundo nó quando o primeiro nó for removido.

assert(
  (function () {
    var test = new LinkedList();
    test.add('cat');
    test.add('dog');
    test.remove('cat');
    return test.head().element === 'dog';
  })()
);

O método remove deve diminuir o length da lista encadeada em um para cada nó removido.

assert(
  (function () {
    var test = new LinkedList();
    test.add('cat');
    test.add('dog');
    test.add('hamster');
    test.remove('cat');
    test.remove('fish');
    return test.size() === 2;
  })()
);

O método remove deve reatribuir a referência do nó anterior ao nó removido para a referência next do nó removido.

assert(
  (function () {
    var test = new LinkedList();
    test.add('cat');
    test.add('dog');
    test.add('snake');
    test.add('kitten');
    test.remove('snake');
    return test.head().next.next.element === 'kitten';
  })()
);

O método remove não deve alterar a lista encadeada se o elemento não existir nela.

assert(
  (function () {
    var test = new LinkedList();
    test.add('cat');
    test.add('dog');
    test.add('kitten');
    test.remove('elephant');
    return (
      JSON.stringify(test.head()) ===
      '{"element":"cat","next":{"element":"dog","next":{"element":"kitten","next":null}}}'
    );
  })()
);

--seed--

--seed-contents--

function LinkedList() {
  var length = 0;
  var head = null;

  var Node = function(element){
    this.element = element;
    this.next = null;
  };

  this.size = function(){
    return length;
  };

  this.head = function(){
    return head;
  };

  this.add = function(element){
    var node = new Node(element);
    if(head === null){
        head = node;
    } else {
      var currentNode = head;

      while(currentNode.next){
        currentNode  = currentNode.next;
      }

      currentNode.next = node;
    }

    length++;
  };

  this.remove = function(element){
    // Only change code below this line

    // Only change code above this line
  };
}

--solutions--

function LinkedList() {
  var length = 0;
  var head = null;

  var Node = function(element){
    this.element = element;
    this.next = null;
  };

  this.size = function(){
    return length;
  };

  this.head = function(){
    return head;
  };

  this.add = function(element){
    var node = new Node(element);
    if(head === null){
        head = node;
    } else {
        var currentNode = head;

        while(currentNode.next){
            currentNode  = currentNode.next;
        }

        currentNode.next = node;
    }

    length++;
  };

  this.remove = function(element){
    if (head === null) {
      return;
    }
    var previous;
    var currentNode = head;

    while (currentNode.next !== null && currentNode.element !== element) {
      previous = currentNode;
      currentNode = currentNode.next;
    }

    if (currentNode.next === null && currentNode.element !== element) {
      return;
    }
    else if (previous) {
      previous.next = currentNode.next;
    } else {
      head = currentNode.next;
    }

    length--;
  };
}