Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 理解链表_Java_Linked List_Singly Linked List_Doubly Linked List - Fatal编程技术网

Java 理解链表

Java 理解链表,java,linked-list,singly-linked-list,doubly-linked-list,Java,Linked List,Singly Linked List,Doubly Linked List,我很难理解课程中的链接列表。我遇到的最大问题似乎是如何存储数据。我看到的代码主要是add(x)在列表中添加一个新节点,但它似乎没有意义 add的代码 boolean add(T x) { Node u = new Node(); u.x = x; if (n == 0) { head = u; } else { tail.next = u; } tail = u; n++; return true; } 这是我所学课程的课本上直接写的。我上网查找

我很难理解课程中的链接列表。我遇到的最大问题似乎是如何存储数据。我看到的代码主要是
add(x)
在列表中添加一个新节点,但它似乎没有意义

add的代码

boolean add(T x) {
  Node u = new Node();
  u.x = x;
  if (n == 0) {
    head = u;
  } else {
    tail.next = u;
  }
  tail = u;
  n++;
  return true;
}
这是我所学课程的课本上直接写的。我上网查找更多资源,并在GITHUB上从更详细的教科书中找到了这段代码。代码太长了,无法直接粘贴

因此,我看到名为“Head”、“Tail”和“u”的类存储信息,如
[Head]->[u]->[Tail]
。此外,当我阅读add方法时,我将存储的信息可视化为
[Head]->[u]->[u]->[u]->[u]->[Tail]

每个节点如何知道要查看哪个“u”节点。每个节点都引用
u
节点。
u
每次都被覆盖,或者获取
u
信息将返回所有
u
的值。
node.next
如何区分每个
u
节点?不应该是代码而不是:

add(x) {
  Node u = new Node();
  u.x = x;
}
更像:

add(x,y) {
  Node y = new Node();
  u.x = x;
}

因此,每个节点都有一个不同的名称来链接到
[Head]->[a]->[b]->[c]->[Tail]

变量名称本身并不重要,因为您认为它们确实重要
u
只是指向节点的一个实例

假设您要创建一个整数链表:

您需要添加(1)。此时,
n=0
。 在
add
方法中,初始化一个新节点。我们只是把它称为
u
。现在,我们将该值设置为
1
。到目前为止,我们已经创建了一个
节点
,其值等于
1

由于,
n=0
,我们的
头部现在也将引用此节点。我们递增,
n++
,以跟踪列表的当前长度。我们还使我们的
tail
引用新添加的节点,因为我们总是将其添加到列表的末尾

现在,您需要添加(2)
。此时,
n=0
。在
add
方法中,初始化一个新节点。我们只是把它称为
u
。现在,我们将该值设置为
1
。我们不需要更新head,因为
1
是列表的第一个节点

但是,我们需要在列表的末尾添加
2
。这意味着
tail
必须引用值为2的新创建的节点。那么,我们如何做到这一点呢?那么,
tail
到现在为止一直是指值为1的节点。因此,我们只需将该节点的next to更新为指向
u
所指向的同一节点(因为这是我们要添加到列表末尾的新创建的节点)


最后,我们将递增
n
,并将
尾部设置为指向刚才添加的节点。

因此,您需要将节点添加到链接列表中

这将创建节点
u
,其中包含相应的信息
x

Node u = new Node();
u.x = x;

现在,有两种选择:

A-这是要添加到链接列表的第一个节点

B-列表上已经有个节点,您正在添加另一个节点

这就是if进入的地方

if (n == 0) {
  head = u;
} else {
  tail.next = u;
}
A-如果
n
(列表中节点的计数器)等于0,则为空。因此,节点
u
是它的头部

B-否则,您将在它的实际
尾部
之后添加一个新节点,因此您将添加对实际
尾部
的引用,表示此节点将是下一个节点


最后,你必须说你要添加的节点是链表的新的
tail
(如果它是空的,那么
u
将同时是
head
tail
)。您还需要增加节点的计数器
n

tail = u;
n++;

从java.util.LinkedList中列出如下所述的节点类:

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;
    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}
私有静态类节点{
E项目;
节点下一步;
节点前置;
节点(上一个节点、E元素、下一个节点){
this.item=元素;
this.next=next;
this.prev=prev;
}
}

节点同时包含下一个和上一个节点,因此每个节点都知道其上一个和下一个节点。

与理解链表相比,您似乎需要花费一些时间来更好地理解Java中对象实例化的概念和范围。但是,要回答您的最后一个问题:不,代码不应该是您所建议的。
u
仅在
add
方法中已知。它是您在方法中为新创建的节点指定的名称,而不是其他名称。因此,节点不像其他类,每个节点都需要一个唯一的标签。u只是对节点的引用,节点本身通过java进行管理。所以实际上它看起来像[Node 0(head)]->[Node 1(u)]->[Node 2(tail)]。这是有道理的。@DrewS我想你还是很困惑
u
只是在
add
方法中为新节点指定的名称。除此之外,它只是一个节点,没有标记。在链接列表中,您知道
,并且可以通过它们的链接到达其他
节点