Как удалить из неизменяемого связанного списка? - PullRequest
0 голосов
/ 15 февраля 2019

Мне нужно создать связанный список, используя метод remove (), который принимает параметр e, универсальный заменитель и удаляет связанный узел, содержащий e, а затем метод возвращает новый связанный список, содержащий все элементы, кромеe.

Я понятия не имею, как реализовать это, и самое длинное, что я получил, это:

  public Set<E> remove(E e) {
    LinkedNode<E> current = null;
    if(!this.contains(e)) {//if this list doesnt contain e, return this
        return this;
    } else {//otherwise go through this set and if it contains e return new set w/out it
        for(E j:this) {
            if(j.equals(e)) {
                current = new LinkedNode<E>(j,current);
            }
        }
    }
    Set<E> newSet = new LinkedSet<E>(current);
    for(E i:newSet) {
        System.out.print(i +", ");
    }
    return newSet;
  }

этот код использует итератор, поэтому работает расширенный цикл for, но он возвращает наборыс неверной информацией.Я думаю, это может быть потому, что в конце нового набора, который я хочу, все еще есть ссылка на конец старого списка, но это всего лишь предположение.

Последний вывод, который я получил, был: d, b, a, c, e, b, d, a, c, e, b, d, a, и входные данные были: c, a, d, b, e

Я пытался удалить c

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Предположим, что в вашем списке нет дубликатов (потому что тип возвращаемого значения является набором) или, по крайней мере, нам нужно удалить только первый случай.

Мы могли бы скопировать элементы текущего списка в новый список раньше 'e 'позиционируйте и используйте элементы после' e 'в качестве хвоста для обоих списков.Таким образом, мы скопируем только часть списка, теперь будут общие элементы.Для неизменяемой коллекции это нормально, но вы должны быть осторожны с другими реализациями методов LinkedList.

public Set<E> remove(E e) {

    if (!this.contains(e)) {
        return this;
    }

    final LinkedNode<E> head = new LinkedNode<E>(this.head);

    // Copy elements of current list to new list before 'e' position
    LinkedNode<E> current = this.head, newListCurrent = head;
    while (!e.equals(current.next)) {
        newListCurrent.next = new LinkedNode<E>(current.next);
        newListCurrent = newListCurrent.next;
        current = current.next;
    }

    // Now current.next is element to remove. Link tail of new list to tail of current list
    newListCurrent.next = current.next.next;
    return new LinkedList<E>(head);
}

Это похоже на псевдокод, но мне нужен полный код вашего LinkedList и LinkedNode, чтобы использовать их правильно.Мне не хватило репутации, чтобы спросить об этом в комментарии))

0 голосов
/ 15 февраля 2019

Если вы возвращаете остальные элементы из метода remove(), вы можете добавить каждый элемент, который не является e:

public Set<E> remove(E e) {
  Set<E> newSet = new LinkedSet<E>();
  for(E j : this) {
    if (!j.equals(e)) {
       newSet.add(j);
    }
  }
  return newSet;
}
...