我正在创建一个堆栈数据结构,并使用链接列表实现它。我使用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的变量,但有人可以向我解释我出错的地方
答案 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()
上)。由于你已经有了尾部,你可以将其附加到尾部指针的末尾。