深度克隆自定义链表

Deep Cloning of Custom Linked List

我正在尝试实现深度克隆自定义链表(矩形对象)的克隆方法。当列表中没有元素或只有一个元素时,我能够获得正确的值,但当列表中有多个元素时,我无法获得正确的值。我认为问题出在我在 MyLinkNode Class 中的克隆方法。有人可以帮我这个吗?

注意:为了便于阅读,我已经缩短了我的代码

class Rectangle implements Cloneable {
    private double width;
    private double height;
    // setters and getters for these class variables

    public Object clone() {
        try {
            Object rectClone = super.clone();
            return (Rectangle) rectClone;
        } catch (CloneNotSupportedException c) {
            return null;
        }
    }
}


public class MyList implements Cloneable {
    private MyListNode head;

    public Object clone() {
        try {
            Object listClone = super.clone();
            if (head != null) {
                ((MyList) listClone).head = (MyListNode) head.clone();
            }
            return (MyList) listClone;
        } catch (CloneNotSupportedException c) {
            return null;
        }
    }
}


class MyListNode implements Cloneable {
    private Rectangle rectangle;
    private MyListNode next;
    // getter setter for class properties

    protected MyListNode clone() {
        try {
            Object NodeClone = super.clone();
            ((MyListNode) NodeClone).rectangle = (Rectangle) rectangle.clone();
            MyListNode temp = this.next;
            while (temp != null) {
                ((MyListNode) NodeClone).rectangle = (Rectangle) rectangle
                        .clone();
                temp = temp.getNext();
                //edited later, posted by mistake
                //clone();
            }
            return (MyListNode) NodeClone;
        } catch (CloneNotSupportedException c) {
            return null;
        }
    }
}

---我使用递归的克隆方法(再次尝试)--

protected MyListNode clone() {
    try {
        Object nodeClone = super.clone();
        MyListNode temp = this.next;

        if( temp == null){
        ((MyListNode) nodeClone).rectangle = (Rectangle)this.rectangle.clone();
        ((MyListNode) nodeClone).next = this.next.clone();
        temp = temp.getNext();
        }
        else{
            clone();
        }

        return  (MyListNode)nodeClone;      


    }catch (CloneNotSupportedException c) {
        return null;
    }


}

--虽然结果似乎是正确的(对之前方法的更正)--

protected MyListNode clone() {
    try {
        Object listNodeCopy = super.clone();
        MyListNode temp = this.next;

        if (temp == null) {
            ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
        } else {
            while (temp != null) {
                ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
                ((MyListNode) nodeClone).next = temp.clone();
                temp = temp.getNext();
            }
        }
    return (MyListNode) listNodeCopy;
    } catch (CloneNotSupportedException c) {
        return null;
    }
}

非常感谢对此的任何帮助!我对克隆和自定义链表都不熟悉,并且已经尝试了很长时间:(

你的迭代方法是错误的。您必须克隆每个节点,因此您必须在列表 class 中执行此操作。如果您在尝试克隆其余节点时尝试在第一个节点上克隆它,它们将递归地克隆其余节点。所以第一个节点将被克隆一次,第二个节点被克隆两次,第三个节点被克隆三次,等等

我会尝试修正你的递归方法。

    if( temp == null){ // <-- temp is null!! should be != null
        ((MyListNode) nodeClone).rectangle = (Employee)this.rectangle.clone(); <-- Employee ?!?!
        ((MyListNode) nodeClone).next = this.next.clone();
        temp = temp.getNext(); <-- This throws NPE as temp is null!! But it is useless anyway. Remove this line.
    }

这确实有效:

protected MyListNode clone() {
    try {
        Object nodeClone = super.clone();
        ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
        if (this.next != null) {
            ((MyListNode) nodeClone).next = this.next.clone();
        }
        return (MyListNode) nodeClone;
    } catch (CloneNotSupportedException c) {
        throw new RuntimeException(c); // <<- This is the best for impossible conditions so if they happen you notice
    }
}

这是我的方法。我认为它工作正常,但有人可以确认吗?

Object nodeClone = super.clone();
        MyListNode temp = this.next;
        if(temp == null){
            ((MyListNode) nodeClone).rectangle = (Employee) this.rectangle.clone();
            return (MyListNode)nodeClone;
        }else{
            while(temp != null){
                ((MyListNode) nodeClone).rectangle = (Rectangle) this.rectangle.clone();
                ((MyListNode) nodeClone).next = this.next.clone();
                temp = temp.getNext();
                return (MyListNode) nodeClone;