我有两个自定义的双向链表和一个方法insertAt(int pos,DoublyLinkedList l),它应该在另一个列表的给定索引之前插入列表l。然而,在使用它之后,没有任何反应,即使我在调试器中观察过程似乎一切正常。程序编译,它只是没有给出任何结果。这是最小的例子:
public class DoublyLinkedList{
private static final class Node {
protected Object data;
protected Node next, prev;
/* Constructor */
public Node() {
next = null;
prev = null;
data = 0;
}
/* Constructor */
public Node(Object d, Node n, Node p) {
data = d;
next = n;
prev = p;
}
/* Function to set link to next node */
public void setLinkNext(Node n) {
next = n;
}
/* Function to set link to previous node */
public void setLinkPrev(Node p) {
prev = p;
}
/* Funtion to get link to next node */
public Node getLinkNext() {
return next;
}
/* Function to get link to previous node */
public Node getLinkPrev() {
return prev;
}
/* Function to set data to node */
public void setData(Object d) {
data = d;
}
/* Function to get data from node */
public Object getData() {
return data;
}
}
protected Node start;
protected Node end;
public int size;
/* Constructor */
public DoublyLinkedList() {
start = null;
end = null;
size = 0;
}
public void insertBefore(int pos, DoublyLinkedList l) {
Node ptr = start;
if (pos == 1) {
l.end.setLinkNext(start);
start.setLinkPrev(l.end);
} else {
for (int i = 2; i <= size; i++) {
if(i==pos){
ptr.setLinkPrev(l.end);
l.end.setLinkNext(ptr);
Node tmp=ptr;
ptr = ptr.getLinkPrev();
ptr.setLinkNext(l.start);
l.start.setLinkNext(tmp);
size=size()+l.size();
break;
}
ptr=ptr.getLinkNext();
}
}
}
public static void main(String[] args) {
// TODO code application logic here
DoublyLinkedList list1 = new DoublyLinkedList();
list1.insertAtEnd("a");
list1.insertAtEnd("b");
list1.insertAtEnd("c");
list1.insertAtEnd("d");
list1.insertAtEnd("e");
DoublyLinkedList list2 = new DoublyLinkedList();
list2.insertAtEnd("1");
list2.insertAtEnd("2");
list2.insertAtEnd("3");
list2.insertAtEnd("4");
list2.insertAtEnd("5");
list1.display();
list2.display();
list1.insertBefore(3, list2);
list1.display();
list1.size();
}
}
任何帮助将不胜感激
答案 0 :(得分:0)
问题在于:
ptr.setLinkPrev(l.end);
l.end.setLinkNext(ptr);
Node tmp=ptr;
ptr = ptr.getLinkPrev();
//ptr is now the last node of l, not the previous node of original list!!!
//==> you cycle your l list again in the next instruction:
ptr.setLinkNext(l.start);
l.start.setLinkNext(tmp);
size=size()+l.size();
break;
您应该在开始合并之前保存ptr的上一个节点...
应该是:
Node tmp = prev.getLinkPrev();
ptr.setLinkPrev(l.end);
l.end.setLinkNext(ptr);
tmp.setLinkNext(l.start);
l.start.setLinkPrev(tmp);
size=size()+l.size();
break;
答案 1 :(得分:0)
查看代码的这一部分:
ptr.setLinkPrev(l.end);
l.end.setLinkNext(ptr);
Node tmp=ptr;
ptr = ptr.getLinkPrev();
ptr.setLinkNext(l.start);
l.start.setLinkNext(tmp);
ptr
的前身,并将其正确链接。ptr
来引用它的前任。但是这个前身并不是原来列表中ptr
的前身。这是上面步骤(1)的结果,即新列表的最终项目!next
与您保存的内容相关联 - 旧的ptr
。因此,您从旧的开始的前向链接仍然是旧方式 - 它们没有太大变化。但是反向链接被破坏了,新列表的链接被破坏了。
您认为没有任何改变,因为您的打印方法可能只是通过其前向链接遍历列表。尝试编写另一种向后推进的打印方法,应该会变得有趣......
解决此问题的一种方法是在替换它之前保存ptr
的前任,并使用它来转发链接新列表。
答案 2 :(得分:0)
我在你的提示人的帮助下想出来了,谢谢。
public void insertBefore(int pos, DoublyLinkedList l) {
checkOutOfBounds(pos);
Node ptr = start;
if (pos == 1) {
l.end.setLinkNext(start);
start.setLinkPrev(l.end);
start=l.start;
size=size()+l.size();
} else {
for (int i = 2; i <= size; i++) {
if(i==pos){
Node tmp=ptr;
ptr.setLinkPrev(l.end);
l.end.setLinkNext(ptr.getLinkNext());
tmp.setLinkNext(l.start);
l.start.setLinkPrev(tmp);
size=size()+l.size();
break;
}
ptr=ptr.getLinkNext();
}
}
}