如何从不可变的链表中删除?

时间:2019-02-14 22:47:36

标签: java linked-list iterator

我需要使用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 :(得分:2)

假设您要从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;
}

答案 1 :(得分:0)

假设您的列表中没有重复项(因为实际返回类型是集合),或者至少我们只需要删除第一次出现的情况。

我们可以将当前列表的元素复制到'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的完整代码才能正确使用它们。我没有足够的声誉在评论中提出这个问题))