堆栈复制构造函数

时间:2017-04-06 16:10:12

标签: java stack copy-constructor doubly-linked-list deep-copy

我的堆栈复制构造函数遇到了很多困难。 DSStack扩展了一个Stack抽象类,并使用一个双向链表来存储数据(标记)。它在构造函数中的行this.push(oldListNode.getToken());处保持失败(NullPointerException)。我已经包含了我认为有助于解决问题的方法/类。它需要是副本。任何帮助或指导都会很棒。

public class DSStack extends Stack {

    // The list containing the data
    private DSList theStack;

    // Constuct an empty stack using a LinkedList as the container
    public DSStack() {
        theStack = new DSList();
    }

    public DSStack(DSStack other) {
    // Create a reference for the stack to be copied
    Node oldListNode = other.theStack.head;

    while (oldListNode != null) {
        this.push(oldListNode.getToken());
        oldListNode = oldListNode.next;
        }
    }

    /**
     * Adds the given object to the top of the Stack. 
     * @return The given object. 
     */
    public Token push(Token obj) {      
        theStack.add(obj);
        return obj;
    }
}

public class DSList implements List {

    /**
     * Appends the specified element to the end of this list.
     * @param obj The object to add. 
     * @return True if the object has been added to the list. 
     * 
     * @throws NullPointerException if the specified object is null.
     */
    public boolean add(Token obj) {
        if (obj == null) {
            throw new NullPointerException();
        }
        // If list is empty, add new node to front.
        if(isEmpty()) {  
            // Create a new Node. Add Token obj as data
            Node newNode = new Node(null, null, obj);  
            // point head to new Node, newNode
            head = newNode;
            return true;
        } else { 
            // create a reference of the start position in the list
            Node current = head;
            // While there are nodes remaining in the list, advance through to reach the end.
            while (current.next != null) 
                current = current.next;
            // Create a new node and append it to the end of the list, with 'prev' pointing to current (2nd to last node)
            Node newNode = new Node(null, current, obj);
            // Point 2nd to last element to the newest , last node in the list (in next variable)
            current.next = newNode;
            // Return true if successful addition of node.
            return true;
        }
    }
 }

public class Node {

    public Node next;
    public Node prev;

    // data being stored in each node
    private Token t;

    // Node constructor
    public Node(Node next, Node prev, Token token) {
        this.next = next;
        this.prev = prev;
        this.t = token;
    }

    public Token getToken() {
        return t;
    }
}

public class Token {

    public enum Type { OPERATOR, OPERAND, PAREN };
    public Type type;

    private String operator;
    private double operand;

    public Token(double result) {
        this.operand = result;
        this.type = Type.OPERAND;
    }

    public Token(String op) {
        this.operator = op;
        this.type = Type.OPERATOR;

        if ( this.operator.equals("(") || this.operator.equals(")") ) {
            this.type = Type.PAREN;
        }
    }

    public Token(Token other) {
        this.operator = other.operator;
        this.operand = other.operand;
        this.type = other.type;
    }
}

2 个答案:

答案 0 :(得分:1)

您必须在您的参数化构造函数theStack中初始化public DSStack(DSStack other)。我没有看到发生这种情况,因此它仍然包含使用参数化构造函数构造的任何对象的空值。请注意,我在讨论theStack方法

中的push引用

答案 1 :(得分:0)

写作构造者有时可能是艺术品。所有你需要做的

public DSStack()
{
    theStack = new DSList();
}

public DSStack( DSStack other )
{
    this();
    // Rest of the code goes on 
    // Create a reference for the stack to be copied
    Node oldListNode = other.theStack.head;

    while (oldListNode != null) 
    {
        this.push(oldListNode.getToken());
        oldListNode = oldListNode.next;
    }

}

这将确保始终初始化 theStack 变量,无论您初始化哪个构造函数为DSStack对象分配内存。 this()语句实际上调用了 no-arg 构造函数,其中初始化了 theStack 变量