Java 反向链接列表

Java 反向链接列表,java,data-structures,linked-list,time-complexity,reverse,Java,Data Structures,Linked List,Time Complexity,Reverse,所以我需要在时间/空间上反转链表 这个实现就是我在Java标准库中仅使用LinkedList类而提出的,它不允许我访问节点本身 不,不是。input.getidx;它本身在时间上是Oidx,这使得您的实现在时间上是二次的 您可能希望使用迭代器或更好的迭代器 编辑:另外,您可以通过稍微重新排列来轻松消除holdPopped holdPopped.add在时间和空间上都是O1,因为您通过传递大小来预先分配空间中的空间 IIRC,holdLL.add也在时间和空间上摊销。有时会更多,有时会更少,但总空

所以我需要在时间/空间上反转链表

这个实现就是我在Java标准库中仅使用LinkedList类而提出的,它不允许我访问节点本身

不,不是。input.getidx;它本身在时间上是Oidx,这使得您的实现在时间上是二次的

您可能希望使用迭代器或更好的迭代器

编辑:另外,您可以通过稍微重新排列来轻松消除holdPopped

holdPopped.add在时间和空间上都是O1,因为您通过传递大小来预先分配空间中的空间

IIRC,holdLL.add也在时间和空间上摊销。有时会更多,有时会更少,但总空间是n,所以它应该平均到On。您可以使用holdl.ensureCapacity简化分析。

不,不是。input.getidx;它本身在时间上是Oidx,这使得您的实现在时间上是二次的

您可能希望使用迭代器或更好的迭代器

编辑:另外,您可以通过稍微重新排列来轻松消除holdPopped

holdPopped.add在时间和空间上都是O1,因为您通过传递大小来预先分配空间中的空间


IIRC,holdLL.add也在时间和空间上摊销。有时会更多,有时会更少,但总空间是n,所以它应该平均到On。您可以使用holdLL.ensureCapacity简化分析。

您要求的更好的方法可以利用Java LinkedList类具有方法这一事实

先添加 addLast 先走 移除 每一个都是O1

在这里,你可以通过几种方式了解时间和空间行为。其中一种方法是:

LinkedList<E> b = new LinkedList<E>();
while (!a.isEmpty()) {
    b.addFirst(a.removeFirst());
}
a.addAll(b);
这会就地进行反转,即变量a始终引用完全相同的对象。这相当于使用堆栈作为临时存储b是堆栈


尽管存在着丑陋的复制,但它是在时间和空间上进行的。

您要求的更好的方法可以利用Java LinkedList类具有方法这一事实

先添加 addLast 先走 移除 每一个都是O1

在这里,你可以通过几种方式了解时间和空间行为。其中一种方法是:

LinkedList<E> b = new LinkedList<E>();
while (!a.isEmpty()) {
    b.addFirst(a.removeFirst());
}
a.addAll(b);
这会就地进行反转,即变量a始终引用完全相同的对象。这相当于使用堆栈作为临时存储b是堆栈


尽管复制过程很难看,但它是在时间和空间上完成的。

Java API有一种方法可以在上完成此操作:。假设这是家庭作业,你应该自己实现,但在现实生活中你会使用库函数

或者,您可以创建一个反向装饰器,使反向O1。这一概念的一个例子如下

public class ReversedLinkedList<T> extends LinkedList<T> {

  private final LinkedList<T> list;

  public ReversedLinkedList(LinkedList<T> list) {
    this.list = list;
  }

  public Iterator<T> descendingIterator() {
    return list.iterator();
  }

  public Iterator<T> iterator() {
    return list.descendingIterator();
  }

  public T get(int index) {
    int actualIndex = list.size() - index - 1;
    list.get(actualIndex);
  }

  // Etc.
}
请注意,它通常是?使装饰者扩展具体类的错误形式。理想情况下,您应该实现公共接口,并接受构造函数参数作为公共接口的实例。上面的示例纯粹是为了说明,因为LinkedList碰巧实现了许多接口,例如出列、列表等


另外,在此处插入典型的“过早优化是邪恶的”注释-如果列表实际上是一个瓶颈,您只会在现实生活中创建这个反向出列类。

Java API有一个方法可以在中完成此操作:。假设这是家庭作业,你应该自己实现,但在现实生活中你会使用库函数

或者,您可以创建一个反向装饰器,使反向O1。这一概念的一个例子如下

public class ReversedLinkedList<T> extends LinkedList<T> {

  private final LinkedList<T> list;

  public ReversedLinkedList(LinkedList<T> list) {
    this.list = list;
  }

  public Iterator<T> descendingIterator() {
    return list.iterator();
  }

  public Iterator<T> iterator() {
    return list.descendingIterator();
  }

  public T get(int index) {
    int actualIndex = list.size() - index - 1;
    list.get(actualIndex);
  }

  // Etc.
}
请注意,它通常是?使装饰者扩展具体类的错误形式。理想情况下,您应该实现公共接口,并接受构造函数参数作为公共接口的实例。上面的示例纯粹是为了说明,因为LinkedList碰巧实现了许多接口,例如出列、列表等

此外,在此处插入典型的过早优化是一个邪恶的评论-如果列表实际上是一个瓶颈,您只会在现实生活中创建这个反向出列类。

您应该始终检查apache commons,它们通常对linkedlist和collections有更好、更灵活的实现

第二,如果您想要反转列表,那么使用双链接列表将更容易

您应该经常检查apache commons,它们对linkedlist和集合有更好、更灵活的实现


第二,如果您想要反转列表,那么使用双链接列表将更容易

啊,我明白了,谢谢你抓住了!理想情况下,我应该使用迭代器。我会修复它的,再次感谢。我更新了我的方法,并在更新的pastebin链接中添加了holdLL.ensureCapacity toonot,我真的不知道该方法,它很酷!我想应该准时
/空间现在啊啊啊,我明白了,谢谢你抓到了!理想情况下,我应该使用迭代器。我会修复它的,再次感谢。我更新了我的方法,并在更新的pastebin链接中添加了holdLL.ensureCapacity toonot,我真的不知道该方法,它很酷!我想现在应该准时了。非常感谢!我改变了它以利用O1方法。我需要在适当的位置反转它,所以我稍微改变了算法。我觉得可以通过保持堆栈的实现来消除来回复制。是否应该使用removeFirst和AddFirst来反转列表,因为removeLast和AddFirst将简单地复制列表,因为这些操作保留了顺序?谢谢@Mark你完全正确!我借此机会整理了答案,并使用了真正的代码。当我给出第一个答案时,我应该测试一下。嘿,非常感谢!我改变了它以利用O1方法。我需要在适当的位置反转它,所以我稍微改变了算法。我觉得可以通过保持堆栈的实现来消除来回复制。是否应该使用removeFirst和AddFirst来反转列表,因为removeLast和AddFirst将简单地复制列表,因为这些操作保留了顺序?谢谢@Mark你完全正确!我借此机会整理了答案,并使用了真正的代码。当我给出第一个答案时,我应该对它进行测试。如果你想看看JDK实现者是如何做到这一点的,请参阅第412-435行。如果你想看看JDK实现者是如何做到这一点的,请参阅第412-435行。我投票关闭这个问题,因为原始代码在外部站点上,请参阅编辑历史,不再可用。我很抱歉投票关闭此问题,因为原始代码位于外部站点上,请参见编辑历史记录,不再可用。