【问题标题】:Why not use ListIterator for full LinkedList Operation?为什么不使用 ListIterator 进行完整的 LinkedList 操作?
【发布时间】:2019-12-23 00:06:09
【问题描述】:

我的主要问题是 ListIteratorIterator 类是否会减少从给定 LinkedList 中删除元素所需的时间,并且在添加元素时也可以这样说使用上述任何一个类的 LinkedList 相同。使用 LinkedList 类本身的内置函数有什么意义?当我们可以使用 ListIterator 函数获得更好的性能时,为什么还要通过 LinkedList 函数执行任何操作?

【问题讨论】:

  • 因为您本身不想 (a) 创建一个迭代器,(b) 迭代到该项目; (c) 删除它。迭代器的remve 工作得更快,因为它忽略了一个重要部分:迭代到正确的节点。
  • 以 LinkedList 函数中的 add(int index, E element) 本身为例。它必须从头本身开始遍历,然后转到正确的索引并将相应的对象放在那里。 ListIterator 也可以做同样的事情,对吗?那么基本的区别是什么? ListIterator有哪些不应该使用的地方?
  • 好吧,要在索引 10 处添加一个元素,您只需要list.add(10, element)。使用迭代器执行此操作需要创建一个迭代器,调用 next() 10 次,最后调用 add()。它的可读性要差得多,更容易出错,而且更冗长。而且速度并不快。你为什么要使用这样一个尴尬的解决方案而不是只使用 add()?
  • @IcyFlamlex:因为它更方便,并且经过有效测试。自己用迭代器做逻辑,需要写更多的代码,而且可能不会考虑一些奇怪的情况(比如负索引等)
  • 好的。清楚地理解了你的解释。

标签: java linked-list iterator time-complexity


【解决方案1】:

ListIterator 确实可以有效地删除它所在的节点。因此,您可以创建一个ListIterator,使用next() 两次移动光标,然后立即删除该节点。但显然您在实际移除之前做了很多工作。

如果您需要构造迭代器,使用ListIterator.remove 并不比通过LinkedList.remove(int index) 删除更有效的“时间复杂度”。 LinkedList.remove 方法需要 O(k) 时间,其中 k 是您要删除的项目的索引。用ListIterator 删除这个元素具有相同的时间复杂性,因为:(a)我们在恒定时间内创建一个ListIterator; (b) 我们调用.next() k 次,每个操作在 O(1) 中; (c) 我们调用.remove(),这又是O(1)。但由于我们调用了.next() k 次,因此这也是一个 O(k) 操作。

.add(..) 在任意位置(“插入”)也会发生类似情况,只是我们这里当然是插入一个节点,而不是删除一个。

现在由于两者具有相同的时间复杂度,人们可能想知道为什么 LinkedList 首先有这样的 remove(int index) 对象。主要原因是程序员的方便。调用mylist.remove(5)比创建一个迭代器,使用循环移动五个位置,然后调用remove更方便。此外,链表上的方法可以防止某些边缘情况,例如负索引等。通过手动执行此操作,您可能会结束删除第一个元素,这可能不是预期的行为。最后,编写的代码有时会被多次读取。如果未来的读者阅读mylist.remove(5),他们会理解它删除了第五个元素,而带有循环的解决方案将需要一些额外的大脑周期来理解该部分在做什么。

正如@Andreas 所说,此外List 接口定义了这些方法,因此LinkedList<T> 应该实现这些。

【讨论】:

  • 的答案“可能有人想知道为什么 LinkedList 一开始就有这样的 remove(int index) 对象” 是它必须实现 List 接口,其中defines 方法。 LinkedList 中没有添加它是因为程序员的方便,它被添加是因为它必须添加。为了程序员的方便,它可能已添加到List,但这是不同的。为什么LinkedList 有它的答案不是程序员的方便。仍然:+1。
猜你喜欢
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
相关资源
最近更新 更多