我对JAVA和OOP相当陌生,我目前正在学习一门学习数学结构和算法的学术课程。
当我学习链接列表的实现时,我遇到了一个小问题,即在实现链接列表时不理解代码如何创建节点(我熟悉构造函数和一点点递归)。
节点类的代码如下
public class Node {
public int info;
public Node next, prev;
public Node (int el) {
this (el,null,null);
}
public Node (int el,Node n,Node p){
info = el; next =n; prev=p;
}
}
我需要知道代码执行时幕后发生的事情(特别是line3如何工作)和 List类的代码如下
public class List {
private Node head, tail;
public List ( ){
head = tail = null;
}
public boolean isEmpty( ){
return head == null;
}
public void addToTail (int el) {
if (!isEmpty ( )) {
tail = new Node (el, null, tail);
tail.prev.next = tail;
}
else head = tail = new Node(el);
}
public int removeFromTail ( ){
int el = tail.info;
if (head == tail)
head = tail =null;
else
{
tail = tail.prev; tail.next = null;
}
return el;
}
}
(这个例子是由我学习的学院提供的,我想知道它是如何工作的)
请解释 Node类的工作原理。
答案 0 :(得分:1)
好的,让我们从Node
班级
public Node next, prev;
public Node (int el) {
this (el,null,null);
}
此处对象next
和prev
是对当前节点的下一个和上一个节点的引用(这是您当前的对象(this))
this (el,null,null);
这意味着您正在创建一个没有上一个或下一个节点的节点。当你传递null时,null为next和previous。它与创建头部类似,并没有下一个和前一个节点。
当您创建头部时,您将永远不会更改它,但是当您在列表中创建第二个元素时,您将更改下一个头部
创建链表的尾部时
public void addToTail (int el) {
if (!isEmpty ( )) {
tail = new Node (el, null, tail);
tail.prev.next = tail;
}
else head = tail = new Node(el);
}
这里首先按tail = new Node (el, null, tail);
创建一个尾节点
然后通过执行tail.prev.next = tail;
每次向列表添加新节点时,您都会调用addToTail(int e1)
来更新尾部并更新旧尾部的下一个。
答案 1 :(得分:0)
我需要知道代码执行时幕后发生的事情(尤其是line3的工作方式)。
请解释Node类的工作原理。
public Node next, prev;
引用对象类型的Java变量是引用,而不是值。字段next
和prev
不是Node对象。没有Node
对象包含其他节点。相反,next
和prev
引用Node
对象分开存储。
如果您来自C或C ++,您可以将这些引用视为指针。
编辑:
如果您反而询问链接列表的构造,则Node类在双向链接列表中表示包含单个项目的单个节点。在双向链表中,每个节点引用之前的节点和之后的节点。
请参阅此相关维基百科文章中的illustration of a doubly linked list。
List
就像一列火车。 Node
就像火车上的一辆汽车。链接是节点之间的引用,类似于列车之间的耦合。您询问的next
和prev
字段是节点之间的链接。
逻辑上,列表包含整个列车。物理上,你的列表引用了火车的头部和尾部,因此它可以从前到后或从后到前穿过节点。
答案 2 :(得分:0)
假设代码的入口点是对:
的调用List list = new List();
list.addToTail(1);
list.addToTail(2);
list.removeFromTail();
第一行代码将构造函数执行到list类中,它只是将head和tail设置为null。
第二行代码添加方法addToTail,并将变量head和tail设置为等于new Node(1),它调用仅在Node类中有一个参数的构造函数。
第三行代码添加方法addToTail,但这次列表不为空,因此脚本输入if语句和使用Node保存的节点(2,null,tail)。如果使用三个参数检查此Node构造函数,则tail(您之前添加的节点值为1)将被设置为与当前节点关联的prev(previous)节点。
最后一行代码删除第二个节点,代码为tail = tail.prev; tail.next = null;并返回刚删除的元素。
答案 3 :(得分:0)
首先在java中的节点是一个特定类型的变量,它可以做一个变量的正常工作,并且有一个其他信息允许她指向你案例中的另一个节点public Node next, prev;
通常在列表中使用节点,想像火车这就是为什么你在这里addtootail
或removefromtail
。
在这个链接中你会找到一个相当详尽的解释。
http://www.vias.org/javacourse/chap14_02.html
答案 4 :(得分:0)
Node类封装数据,在本例中为一个名为info
的整数值。
此外,List
实现为Nodes
的序列。
next
中prev
和Node
值的原因是节点可以链接到列表序列中的上一个和下一个节点。访问列表中节点的唯一方法是遍历列表,使用next
引用转发,或使用prev
引用转发。
请注意,列表不支持像数组那样的随机访问。要获取元素,您需要在某个方向上遍历列表。