我写了一个圆形的双向链表,前面有一个虚拟节点。在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();
}
}
答案 0 :(得分:1)
欢迎来到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
)的单独变量。
答案 1 :(得分:0)
我已经解决了这个问题。我没有设置curr = dummy,而是设置了curr = head。在DLL顶部初始化虚拟对象后,立即将head设置为dummy。这样一来,我就不会改变自己的头脑。