合并自定义双向链表

时间:2015-03-14 20:05:31

标签: java doubly-linked-list

我有两个自定义的双向链表和一个方法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();
}
}

任何帮助将不胜感激

3 个答案:

答案 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);
  1. 它将新列表的结尾设置为ptr的前身,并将其正确链接。
  2. 临时变量保持对ptr的当前引用。
  3. 然后你移动ptr来引用它的前任。但是这个前身并不是原来列表中ptr的前身。这是上面步骤(1)的结果,即新列表的最终项目!
  4. 然后你告诉这个项目,新列表的结尾,链接到新列表的开头......新列表现在将成为一个圆圈。但只是单链接。
  5. 然后,您将开始的next与您保存的内容相关联 - 旧的ptr
  6. 因此,您从旧的开始的前向链接仍然是旧方式 - 它们没有太大变化。但是反向链接被破坏了,新列表的链接被破坏了。

    认为没有任何改变,因为您的打印方法可能只是通过其前向链接遍历列表。尝试编写另一种向后推进的打印方法,应该会变得有趣......

    解决此问题的一种方法是在替换它之前保存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();
        }

    }

}