我写了一个循环双链接列表,前面有一个虚拟节点。在初始化DLL类的过程中,我创建了虚拟节点。当我在jGrasp中使用调试器并使用可视化工具时,在插入几个数字后,我的虚拟节点会四处移动,不会停留在最前面。我不明白我是如何修改我的链表的。作为前言,我的节点类有一个整数val和两个名为prev和next的指针。我注意到的一件事是,在赋值语句curr=dummy之后,dummy节点被洗牌到上一次插入的curr。
public class DLL {
Node curr;
Node help;
Node dummy = new Node(null, null, -1);
public DLL() {
this.curr = curr;
this.help = help;
dummy.next = dummy;
dummy.prev = dummy;
}
public boolean isEmpty() {
if (dummy.next == dummy && dummy.prev == dummy) {
return true;
}
return false;
}
public void push(int elem) {
if (isEmpty()) {
Node sec = new Node(dummy, dummy, elem);
dummy.next = sec;
dummy.prev = sec;
} else {
curr = dummy;
while (curr.next != dummy) {
curr = curr.next;
}
Node n = new Node(curr, dummy, elem);
curr.next = n;
dummy.prev = n;
}
}
public void reverse() {
curr = dummy;
help = dummy;
while (curr.next != help || curr != help) {
curr = curr.next; // increment curr
help = help.prev; // decrement help
swap(curr, help); // swap
}
}
public void swap(Node curr, Node help) {
int temp = curr.val;
curr.val = help.val;
help.val = temp;
}
public boolean contains(int elem) {
curr = dummy.next;
while (curr != dummy && elem != curr.val) {
curr = curr.next;
if (curr == dummy) {
return false;
}
}
return true;
}
}
以下是我使用的小测试类:
public class testDLL {
public static void main(String[] args) {
DLL dlink = new DLL();
dlink.push(4);
dlink.push(6);
dlink.push(3);
dlink.push(2);
assert dlink.contains(4) == true;
assert dlink.contains(6) == true;
assert dlink.contains(3) == true;
assert dlink.contains(2) == true;
dlink.reverse();
}
}
我相信我已经解决了这个问题。我没有设置curr=dummy,而是设置curr=head。在DLL顶部初始化dummy之后,我立即设置head=dummy。这样我就不会在前进中改变头部。
欢迎来到SO。我将建议你如何自己解决问题,而不是为你找出问题所在。
您的测试试图一次测试太多。为了让您的测试工作,所有的方法都需要工作。更好的是(尽可能地)孤立地测试每个方法,然后构建以测试更复杂的场景。
所以先试着让这个测试起作用:
DLL list = new DLL();
assertTrue(list.isEmpty());
然后呢
DLL list = new DLL();
list.push(5);
assertTrue(list.contains(5));
很快,你就会发现你需要一种方法来获取不同格式的列表,以便进行测试。这很典型。
DLL list = new DLL();
list.push(5);
list.push(7);
list.push(5);
assertEquals(list.asList(), List.of(5, 7, 5));
DLL list = new DLL();
list.push(5);
list.push(7);
list.reverse();
assertEquals(list.asList(), List.of(7, 5));
等等
这样,在继续之前,您可以检查每个方法是否适用于基本值。
现在有几个设计要点:使用虚拟节点存储头部和尾部是不寻常的。很容易搞乱价值观(就像你所做的那样)。更好的方法是将头部和尾部存储为单独的变量,如果列表为空并指向单个项目的同一个节点,则这些变量为null
(或者更好的方法是可选。empty
)。
我尝试实现循环链表的insert方法。我想我取得了一些成功。 问题:当我显示列表时。display方法将循环,因为链接的每个next变量都链接到一个非Null节点对象。所以head永远不会是空对象。根据我对单链表的回忆,head总是指向列表中的第一个节点或其中包含数据的第一个节点。 我对循环链表的概念理解:根据我的理解,循环链表有点像一个单链表,但有一点小的变化:尾部对象的下一个变量指向头部。 来
输出 谁能告诉我这里发生了什么?有什么不同?
我理解得对吗?(从虚拟节点开始) dummy->a->b->c->d->dummy(环绕到dummy节点) 因此,如果我想删除第一个实际的数据段(A),我需要将它分配给一个临时变量。所以Node first=head.next。然后我需要有一个虚拟的头部引用“B”,所以我需要做head.next=first.next。这就是所有需要做的吗? 在从列表中删除任何节点N的情况下(假设它在列表中),这是
我有一个双链接列表,看起来像: 当我使用迭代器和下面的代码遍历列表时,输出会精确打印上面写的内容。 但是,我希望在遍历列表时跳过空节点,以便它只打印: 我无法让我的代码做到这一点。这是我迄今为止所想出的。 问题是我得到了一个NoTouchElementException错误,但我不知道如何修复它。我猜是因为当我到达第二个空虚拟节点时,我试图跳过它,但没有其他节点可以跳到。 我的问题是,如何更改代码
我正在尝试创建一个函数,用于在双链接列表的末尾添加。我无法精确指出为什么它没有打印出任何内容。 当我构建程序时,没有出现错误。 我正在确定。新建节点首先检查头部是否有任何值 在上一个当前指针之后创建 我将前一个节点连接到新节点,新节点指向前一个节点,而新节点指向nullptr作为下一个节点。
问题内容: 我想打印根节点的子元素。这是我的XML文件。 根据我的理解,根节点是“公司”,其子节点必须是“职员”和“职员”(因为存在“职员”节点2次)。但是,当我尝试通过我的Java代码获取它们时,我得到了5个子节点。3个额外的文本节点从哪里来? Java代码: 输出: 为什么三个文本节点要过来? 问题答案: 为什么三个文本节点要过来? 它们是子 元素 之间的空白。如果只需要子元素,则应忽略其他类