[英]Java: When I insert into my circular doubly-linked list with a header dummy node, my dummy node is shuffled around. Why?
我已经写了一个圆形的双向链表,前面有一个虚拟节点。 在DLL类的初始化期间,我创建了虚拟节点。 当我在jGrasp中使用调试器并使用可视化工具时,在插入多个数字后,我的虚拟节点会乱七八糟,不会停留在最前面。 我不了解如何修改链表。 作为序言,我的节点类具有一个整数val和两个名为prev和next的指针。 我注意到的一件事是,在赋值语句curr = 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();
}
}
欢迎来到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
(或者最好是Optional.empty
)。
我相信我已经解决了这个问题。 我没有设置curr = dummy,而是设置了curr = head。 在DLL顶部初始化虚拟对象后,立即将head设置为dummy。 这样一来,我就不会改变自己的头脑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.