对于显示的代码,究竟有什么区别。根据我的理解,它应该返回 current.data 值,并将当前指针更改为 current.next。此外,谁能解释当前.prev.next = ...和电流 = ...通常?双链列表,仍然让我有点困惑。谢谢!
public T next() {
if (!hasNext()){
throw new NoSuchElementException();
}
T data = current.data;
current = current.next;
return data;
}
与
public T next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
current = current.next;
return current.prev.data;
}
TL;DR~
如果您有一个双向链表,并且该节点同时具有以前的node
和next
节点。 说node->previous->next
确实会让你回到起点。 但是如果你在列表的头部或尾部,代码就会崩溃(因为它正在尝试NULL->next
)。 所以不要那样做。
好吧,让我们暂时忘记数据结构。
想象一个"节点"是一个穿着T恤的人。 T恤上到处都写着他们的名字(数据)。
在第一种情况下,人们排成一排,都面向同一个方向,后面的人伸出手臂,指向他们前面的人。 如果你正在寻找"乔",你可以看看当前的人是否是"乔",以及是否有另一个人要检查("乔"指向谁,或者他是否是最后一个人)。
这是一个单链表。 每个人都只知道自己和下一个人。每个人只能"看到"前面的人,而不能"看到"后面的人。 要找出一个人的名字,你必须问这个人自己,或者指着他们的人。 也就是说,问node.data
或node->next.data
。 你可以问这个人谁是下一个,但不能问谁是上一个。 他们不知道谁是以前的。
现在想象一下,人们侧身排成一条线,指向两边的两个人。 这是一个双向链表。 每个人都指向前一个人和下一个人。 任何给定的人都可以告诉你他们的名字,以及他们所指的人的名字。 也可以沿着人员列表向两个方向移动,因为他们可以告诉你他们在两个方向上指向谁。
这给了我们一些代码:
structure NodeSingle
{
String name;
NodeSingle next;
}
和
structure NodeDouble
{
String name;
NodeDouble previous;
NodeDouble next;
}
所以我们从一个空的(单链接的)列表开始。
随之而来的是"鲍勃"。 Bob 没有人可以指向(没有下一个,也没有上一个),所以在数据方面我们得到["Bob", <>]
.
然后是"莎莉"。 无论出于何种原因,我们都希望列表按字母顺序排序。 所以我们看着鲍勃,并决定莎莉需要下一个。 所以我们让鲍勃指着莎莉。["Bob", <Sally>]
和["Sally", <>]
.
然后是"恩斯特",他必须在鲍勃和莎莉之间穿梭:["Bob", <Ernst>]
["Ernst",<Sally>]
["Sally", <>]
在编程术语中,这是使用node->next
的地方。当我们添加"莎莉"时,我们可以说["Bob"]->next = new NodeSingle("Sally")
.
如果[Sally]
必须在[Bob]
和[Tina]
之间穿梭,那么显然["Bob"]->next = new NodeSingle("Sally", <Tina>)
双向链表大致相同,除了前面的指针也需要处理。
因此,在编程时,可以引用节点:node->next->next
...等。 如果定义了next
和prev
(这是一个很大的如果),则用于沿链移动。
想象一下一个简单的搜索功能:
// Return the node with name = <for_this_name> or NULL
NodeSingle *find(NodeSingle *list, String for_this_name)
{
while (list != NULL && list->name != for_this_name)
list = list->next; // skip to next node
return list;
}