根据定义,Linked List是一个列表,它的每个元素引用下一个元素(如果我们正在谈论双链表,那么前面的元素。) http://en.wikipedia.org/wiki/Linked_list
然而,在Java中,LinkedList实现了List,Queue,Deque等。 http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html
您无法在LinkedList中找到一个方法,它为您提供列表中的下一个或上一个对象,您可以做的最好的方法是获取Iterator并获取对象。我的问题是为什么Java已经调用了这个数据结构LinkedList,而它不是真正的链表?链接列表可以用Java实现,如下所示:
Public class MyLinkedList{
public int value;
public MyLinkedList next;
}
答案 0 :(得分:6)
您无法在LinkedList中找到一个方法,该方法为您提供列表中的下一个或上一个对象
不,这完全合适。 “列表中的下一项”的概念在列表中没有意义。它对列表中的节点非常有意义,但这不是Java API公开的内容。它当然是内部存在的 - 只是没有暴露。如果要遍历列表,则使用迭代器。您仍然可以在开头或结尾添加,从开头或结尾删除,以及从迭代器添加/删除。
虽然您确实可以将“节点”和“列表”的概念混淆为您建议的示例代码,但我认为这通常不是一个好主意。
换句话说:你想要实现是什么导致你出现问题?我相信你应该能够使用公共API做你想做的事 - 你可能根本没有注意到它。
答案 1 :(得分:5)
我的问题是为什么Java调用了这个数据结构LinkedList,而它不是真正的链表?
因为它的实现是一个链表。来自the documentation:
List
和Deque
接口的双链表实现。实现所有可选列表操作,并允许所有元素(包括null
)。
LinkedList
是通过链接列表实现的List
,ArrayList
是使用数组等实现的List
。您选择哪一个可能对于运行时特征。例如,来自LinkedList
文档:
所有操作的执行都与双向链表一样。索引到列表中的操作将从开头或结尾遍历列表,以较接近指定索引为准。
例如,您知道next
来自Iterator
或iterator
的{{1}}将非常有效,但是listIterator
by index将涉及遍历。
答案 2 :(得分:3)
集合是链表还是数组列表与其合同无关,而与其实现有关。 LinkedList
确实是实施的链接列表,合同是java.util.List
。
它显示的不是它的API,而是它的空间/时间复杂性特征,任何熟悉链表的人都可以轻松预测。
作为参考,这是LinkedList
节点的实际实现,非常符合您的期望:
957 private static class Node<E> {
958 E item;
959 Node<E> next;
960 Node<E> prev;
962 Node(Node<E> prev, E element, Node<E> next) {
963 this.item = element;
964 this.next = next;
965 this.prev = prev;
966 }
967 }
答案 3 :(得分:1)
除了其他人的正确答案之外,如果接口的底层实现是链接列表,则实现对象将有一个方法来获取列表中的下一个项目。该方法不作为合同的一部分公开。
实现是链表的事实会影响List合同的各种方法的Big-O性能。
答案 4 :(得分:0)
然而,在Java中,LinkedList实现了List,Queue,Deque等。
根据API,LinkedList实现了这些接口,因此可以使用任何这些结构。
答案 5 :(得分:0)
当我读完你的问题时,我感觉你没有区分链表的概念和链表的实现。
您的示例代码很好地演示了链表的概念,但这并不意味着它是实现链表的唯一方法或最佳方式。我相信您可以使用内置的LinkedList
类执行标准链接列表所需的任何操作,尽管您可能会在数据结构类或教科书中看到一组不熟悉的API。
所以基本上,只要你能在O(1)
时间内实现插入操作,在O(1)
时间内删除操作,在O(n)
时间内进行搜索操作等,它就是链表。与其他数据结构(如数组)的时间复杂性形成对比。
内置LinkedList
没有直接提供next
操作,而是通过其迭代器提供。这只是Java语言的设计决策,因为您可能会受益于Iterator pattern。
Java是一种典型的面向对象语言,其主要特征之一是Abstraction。
答案 6 :(得分:0)
所以我不知道@Marko从哪里读取该实现,但是1.8 jdk中的实现却大不相同。
首先,声明的第一个变量是:
transient int size = 0;
每当将节点添加到列表时,该值就会增加。这意味着列表中存在Integer.MAX_VALUE(2147483647)节点的固有限制。在现代世界中,这个数字并没有看起来那么大。问题不在于我们没有一个真正的链接列表(创建起来很简单),而是对于所有第3方库,他们很可能不会考虑这一点,然后整个库都无法使用。