新列表中链接列表中的重复项目

时间:2017-02-08 15:06:34

标签: java algorithm data-structures

我试图深入复制节点列表。 例如我的清单如下:

Node n = new Node(1,new Node(12, new Node(34, new Node(3, Node.NIL))));

和我的功能:

    public Node copy() {

       Node initial= this;
       Node duplicate=new Node(initial.getItem());

       while(Node.NIL!=initial.getNext()){

           initial=initial.getNext();
           Object a = initial.getItem();
           duplicate.next=new Node(a);
       }

       return duplicate;
    } 

所以当我这样做时,输出列表是重复的[1,3]。我不明白12和34在哪里。

2 个答案:

答案 0 :(得分:2)

在此步骤duplicate.next=new Node(a);上,您每次都会覆盖duplicate.next的上一个值。创建下一个节点时,应在每个步骤更改duplicate上的引用。

您可以使用递归来创建下一个节点的副本,然后创建新节点:

    public Node copy() {
        Node initial= this;
        Node copyNext = this.getNext() == NIL? NIL : this.getNext().copy();
        Node duplicate = new Node(initial.getItem());
        duplicate.next = copyNext;
        return duplicate;
    }

没有递归:

    public Node copy() {

        Node currentNode= this;
        Node firstDuplicate = new Node(currentNode.getItem()); //save reference for first node to return
        Node currentDuplicate=firstDuplicate;

        while(Node.NIL!=currentNode.getNext()){
            Node nextNode = currentNode.getNext();
            Node nextCopy = new Node(nextNode.getItem()); //create copy of next
            currentDuplicate.next = nextCopy; //assign this copy as next for current duplicated node
            currentDuplicate = nextCopy; //change reference for current duplicated node to copy 
            currentNode = nextNode; 
        }

        return firstDuplicate;
    }

如果我理解你,你需要创建恢复列表。在这种情况下,您不需要创建初始列表的新副本。

    public Node reverse() {
        Node head = NIL; //initial we have a empty list

        Node current = this; //set cursor to current node

        while (current != NIL) {
            Node copy = new Node(current.getItem()); //create a copy of current node
            copy.next = head; //set head node as next for copy 
            head = copy; //now move head to copy 
            current = current.next; // move cursor for next position
        }

        return head;
    }

使用递归创建反向列表,您只需要其他方法来保留对先前创建的副本的引用:

    public Node reverse() {
        if (this == NIL) {
            return NIL;
        }

        return reverse(new Node(this.getItem(), NIL), this.getNext());
    }

    private Node reverse(Node head, Node tail) {
        Node copy = new Node(tail.getItem()); 
        copy.next = head;
        if (tail.getNext() == NIL) {
            return copy;
        }
        return reverse(copy, tail.next);
    }

答案 1 :(得分:0)

public Node reverse(){

    Node p= this;
    Node firstDuplicate = new Node(p.getItem()); //save reference for first node to return
    Node currentDuplicate=firstDuplicate;

    while(Node.NIL!=p.getNext()){
        Node nextNode = p.getNext();
        Node nextCopy = new Node(nextNode.getItem());
        currentDuplicate.n = nextCopy;
        currentDuplicate = nextCopy;
        p = nextNode;
    }


          /* If the list is empty */
          if(firstDuplicate == NIL)
              return Node.NIL;

          /* If the list has only one node */
          if(firstDuplicate.n == Node.NIL)
              return firstDuplicate;

         // Node reverseRest = new Node(p.getItem(),Node.NIL);
          Node rest = new Node(); 
          rest = firstDuplicate.getNext();

          firstDuplicate.setNext(Node.NIL); 
         // Node reverseRest=new Node(p.getItem(),reverseRest);

         Node reverseRest=new Node();
           reverseRest = rest.reverse();

          /* Join the two lists */
          rest.setNext(firstDuplicate); 
          //p=this;
        //  p=p.nthNext(0);
          return reverseRest;
      }