线程“main”中的异常java.lang.NullPointerException错误 - Eclipse Java链接列表

时间:2014-03-04 15:48:56

标签: java eclipse nullpointerexception linked-list stack

我正在创建一个堆栈数据结构,并使用链接列表实现它。我使用3个java文件 - stack.java,stacktest.java和linkedList.java。链接列表在我测试时工作正常但是堆栈测试给了我以下错误

Is Empty?: true
Is Empty?: false
Exception in thread "main" java.lang.NullPointerException
    at Stack.Peek(Stack.java:56)
    at StackTest.main(StackTest.java:12)

这是我的stack.java文件

 import java.util.EmptyStackException;

public class Stack{

    linkedList list;
    int count;

    public Stack()
    {
        list = new linkedList();
        count = 0;
    }

    /**
     * Adds a node to the head of the list
     * @param c character to add
     */
    public void Push(char c)
    {
        if(list.isEmpty())
        {// If the list is empty
            list.addFirst(c); // Add first
            count++;
        }
        else
        {
            list.addAtEnd(c); // To the end (tail acts as head)
            count++;
        }
    }

    /**
     * Removes a node from the head of the list
     * @return char removed node
     */
    public char Pop() throws EmptyStackException 
    {
        if (!isEmpty())
        {
            return list.removeLast();
        }
        else
        {
            throw new EmptyStackException();
        }
    }

    /** 
     * Returns the char from the head of the list
     * @return char from top of the list
     */
    public char Peek() throws EmptyStackException 
    {
        if (!isEmpty())
        {
            return list.getTail().ch;
        }
        else
        {
            throw new EmptyStackException();
        }
    }

    /**
     * Is the list empty?
     * @return true=yes false=no
     */
    public boolean isEmpty()
    {
        return list.isEmpty();
    }

    /**
     * Counts number of nodes within the list
     * @return int # nodes in list
     */
    public int getCount()
    {
        int counter = 0;
        Node temp = list.getHead(); // Get head pointer.
        while(temp.next != null) // Iterate until tail is reached.
            counter++; // Increment counter on each node
        return counter;
    }

    public void printStack()
    {
        list.printList();
    }
}

我的stacktest.java

   import java.io.IOException;

public class StackTest {

    public static void main(String args[]) throws IOException
    {
    Stack stackList = new Stack();
    System.out.println("Is Empty?: " + stackList.isEmpty());
    stackList.Push('A');
    System.out.println("Is Empty?: " + stackList.isEmpty());
    stackList.Pop();
    stackList.Peek();
    stackList.isEmpty();
    stackList.getCount();
    stackList.printStack();

    }

}

我的linkedList.java

    class Node
{
    protected char ch;
    protected Node next;
    protected Node previous;

    /**
   * Construct a node with the given character value 
   * @param c - The character 
    */
    public Node (char c)
    {
        this.ch = c;
        this.next = null;
        this.previous = null;
    }
}   

public class linkedList
{  /** A reference to the head of the list */
    protected Node head;
    protected Node tail;
    /**
   * Construct a new empty list 
    */
    public linkedList()
    {
        head=null;
        tail=null;
    }

    public Node getHead()
    {
        return head;
    }

    public Node getTail()
    {
        return tail;
    }

/**
 *Set c as first node in the list
 *@param c The character to be inserted
 */
    public void addFirst(char c)
    {
        Node newNode = new Node(c);
        head=newNode; // Adding new element.
        tail=newNode; // Head and tail will be the same.
    }

    /**
 *Add a character to the end of the list 
 *@param c The character to be inserted
 */
    public void addAtEnd(char c)
    {
        Node nod = new Node(c);
        Node temp = head;
        while (temp.next != null) // cycle until at end of list.
            temp = temp.next;
        temp.next=nod; // last element is new node.
        nod.previous=temp; // linking last node with rest of list.
        tail=nod; // new node is the tail.
    }

    /**
     *Add a character in alphabetical order into the list 
     *@param c The character to be inserted
    */
    public void addInOrder(char c)
    {

        Node n= new Node(c);

        if(isEmpty())
        {
            addFirst(c);
        }
        else
        {
        Node pre=head;
        Node succ= head.next;
        if (n.ch < pre.ch)
            {
                n.next =head;// join node n to the list at the head.
                head = n;// head is reading from n.
            }
        else
        {

        while(succ!=null && n.ch > succ.ch)
        {   // find the position to insert the node
            pre = succ;
            succ = pre.next;

        }   //rearrange pointers    
       n.next = succ;
       pre.next = n;
        }
        }
    }
    /**
     *Test to see if this list is empty 
     *@returns true or false
    */  
    public boolean isEmpty()
    {
        return (head == null && tail == null);
    }


    /**
     *removes a node from the head of the list 
     *@returns c The character from the removed node
    */
    public char removeFirst() 
    {
        if(!isEmpty())
        {
    // a temporary pointer to enable return of the char being removed
            Node temp = head;
            head = head.next;   //  move head pointer along the list
            return temp.ch;
        }
        else 
        {
            System.out.println("List is empty");
            return '?'; //to indicate that the list is empty
        }
    }

    /**
     * removes a node from the tail of the list 
     * @return c The character from the removed node
     */
    public char removeLast()
    {
        Node t = getTail(); // Retrieve tail
        tail = t.previous; // Set tail to previous node
        return t.ch; // return character
    }

    /**
     *prints the characters in the list
    */
    public void printList()
    {
        Node temp=head;
        while(temp!=tail.next)
        {
            System.out.print(temp.ch + " ");
            temp=temp.next;
        }
        System.out.println(); // After print, goes to new line.
    }

}

我知道我使用的是一个null的变量,但有人可以向我解释我出错的地方

3 个答案:

答案 0 :(得分:1)

当您致电addFirst()时,它会将头部和尾部设置为新节点。但是,当您removeLast()时,它只会将tail更改为null并将head设置为您弹出的节点。

然后,当您致电isEmpty()时,由于head不是null,因此它无法识别该列表是空的并返回false。

您需要修改removeLast()以检查是否删除了列表中的唯一元素,并相应地更新了头部。

答案 1 :(得分:0)

一旦弹出了堆栈中唯一的元素,内部列表就为空。因此list.getTail()将返回null,您无法再查看堆栈。

答案 2 :(得分:0)

StackTest.java中,您将一个元素插入堆栈,然后弹出它,然后尝试查看堆栈。您的pop功能正在使用removeLast linkedList.java方法。当您正确地将尾部指向tail.previous时,您还需要检查结果是否导致尾部变为空(这意味着您已删除链接列表中的最后一个元素)。你应该在removeLast中检查这个,如果是这样的话,make head = tail:

public char removeLast()
{
    Node t = getTail(); // Retrieve tail
    tail = t.previous; // Set tail to previous node
    if(tail == null){
        head = tail;
    }
    return t.ch; // return character
}

如果您弹出列表中的最后一个元素,这种isEmpty()方法将始终返回true。您必须对removeFirst()进行类似的更改,如下所示:

public char removeFirst() 
{
    if(!isEmpty())
    {
// a temporary pointer to enable return of the char being removed
        Node temp = head;
        head = head.next;   //  move head pointer along the list
        if(head == null){
            tail = head;
        }
        return temp.ch;
    }
    else 
    {
        System.out.println("List is empty");
        return '?'; //to indicate that the list is empty
    }
}

在您更改之后,当您尝试查看空堆栈时,peek()方法现在将抛出EmptyStackException(这是可取的)而不是NPE。 我可能还建议您不需要遍历整个列表以在列表的末尾添加(在addAtEnd()上)。由于你已经有了尾部,你可以将其附加到尾部指针的末尾。