Steque 和 API 实现
Posted
技术标签:
【中文标题】Steque 和 API 实现【英文标题】:Steque and the API implementations 【发布时间】:2016-04-15 05:37:58 【问题描述】:一个 steque 是一个堆栈结束队列,它是一种数据类型,它实现了 push、pop 和 enqueue 以及您希望添加的任何其他功能。
请注意,我正在使用基于链表的方法来实现 steque。下面是我的整个 Steque 类的代码,我遇到的问题是,每当我尝试从 steque 中弹出一些元素或迭代它时,我都会得到 NullPointerException。 push() 和 enqueue() 方法在我测试时似乎工作得很好,我确实彻底检查了我的 pop() 和 iterator(),但似乎找不到任何可能导致任何 NullPointerException 的错误。对于我的代码如何解决这个问题的任何帮助将不胜感激!
public class Steque<Item> implements Iterable<Item>
private int N;
private Node first;
private Node last;
private class Node
private Item item;
private Node next;
private Node prev;
/**
* create an empty steque
*/
public Steque()
N = 0;
first = null;
last = null;
/**
* pop (return) the first item on top of stack and modify first
* accordingly to refer to next node.
*/
public Item pop()
if (isEmpty()) throw new RuntimeException("Steque underflow");
Item item = first.item;
first = first.next;
N--;
return item;
/**
* push item on top of the stack and modify the first pointer
* to refer to the newly added item.
*/
public void push(Item item)
Node oldfirst = first;
Node first = new Node();
first.item = item;
first.next = oldfirst;
if (oldfirst != null)
oldfirst.prev = first;
++N;
/**
* push item on bottom of the stack and reset the last pointer
* to refer to the newly added item.
*/
public void enqueue(Item item)
Node oldlast = last;
Node last = new Node();
last.item = item;
last.prev = oldlast;
if (oldlast != null)
oldlast.next = last;
++N;
public Item peek()
if (isEmpty()) throw new RuntimeException("Steque underflow");
return first.item;
public boolean isEmpty()
return N == 0;
public int size()
return N;
/**
* prints the steque from top to bottom
private void printState()
System.out.println("Printing steque below: top --> bottom ");
for (Node idx = this.first; idx!= null; idx = idx.next)
System.out.print(idx.item + " - ");
System.out.println();
*/
public String toString()
StringBuilder s = new StringBuilder();
for (Item i : this)
s.append(i + " ");
return s.toString().trim();
public Iterator iterator()
return new LIFOIterator();
/**
* iterator that implements hasNext(), next(), and remove().
*/
private class LIFOIterator implements Iterator<Item>
// support LIFO iteration
private Node current = first;
public boolean hasNext() return current.next != null;
public void remove()
Node n = first;
while (n.next.next != null)
n = n.next;
n.next = null;
--N;
public Item next()
if (!hasNext())
throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
/**
* a simple test client
*/
public static void main(String[] args)
Steque<String> steq = new Steque<String>();
while (!StdIn.isEmpty())
String item = StdIn.readString();
if (!item.equals("-"))
//steq.push(item);
steq.enqueue(item);
/*
else if (!steq.isEmpty())
System.out.print(steq.pop() + " ");
*/
System.out.println("(" + steq.size() + " left on steque)");
Iterator itr = steq.iterator();
System.out.println("printing steque of strins below: ");
while(itr.hasNext())
System.out.print(itr.next() + " ");
注意:我在这里省略了所有的 import 语句,但它们确实包含在我的程序中,因此保证此代码中没有“未定义的方法”或“未声明的标识符”错误。
【问题讨论】:
StdIn
类型不是标准 Java 类型。这使得很难复制和粘贴您的程序并尝试查找错误。
您的last
和first
没有以任何方式连接。尝试在新的 steque 上执行下一个代码:steq.enqueue("asd"); steq.pop();
@user3707125 last 和 first 不应该直接连接,它们代表顶部和底部堆栈,如果你愿意的话,在堆栈中。
@jah 是的,我知道这一点。 StdIn 是由一些普林斯顿 CS 教授编写和定义的,旨在“帮助”学生以最少的 Java 知识进行学习。如果您要复制和粘贴来测试代码,则可能需要使用扫描仪。
【参考方案1】:
问题是,当您仅使用 enqueue 方法时,您的 first
变量不会被填充。
因此,访问该字段的方法会触发 NPE。
hasNext 通过current
使用该字段。
IMO 的解决方案是在 enqueue 中捕获 N == 0 的特殊元素,并用可用元素填充第一个元素。
我试过了
if(N==0)
first = last
在 enqueue 中初始化 last 之后,它可以在没有 NPE 的情况下工作。
【讨论】:
我明白你的意思,我已经对我的 push() 和 enqueue() 方法进行了相应的更改,但是每当我尝试调用这两种方法时,我仍然会收到 NPE,我在 push() 中所做的更改) 是我添加了 else 情况,如果 steque 最初是空的,那么我将设置 last = first。出于同样的原因,在我的 enqueue() 方法中,我添加了 else 条件,如果 steque 最初是空的,那么我将设置 first = last。关于这仍然给我NPE的任何建议?非常感谢:) 你真的不需要“其他情况”。您只需要一个如上所示的 if 条件。显然在last初始化之后。我检查了入队,它在没有 NPE 的情况下工作。也许你应该发布相应的 sn-ps。 我一直在测试我的代码,真的无法弄清楚我在以下哪个方法中出错了,我在此处附加了多个 pop()、push() 和 enqueue() cmets,因为它们不适合单个评论块:public Item pop()
if (isEmpty()) throw new RuntimeException("Steque underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null;
return item;
这是我的 push() 方法: public void push(Item item) Node oldfirst = first;节点优先 = new Node(); first.item = 项目; first.next = oldfirst; if (oldfirst != null) oldfirst.prev = first; else // 如果只有一个元素 last = first; ++N;
即使在我阅读了规则之后,也不确定如何在评论中格式化代码的 sn-p,但这是我的 enqueue() 方法:--- --- public void enqueue(项目 item) 节点 oldlast = last;上一个节点 = 新节点();最后一个项目 = 项目; last.prev = oldlast; if (oldlast != null) oldlast.next = last; if (last.prev == null) first = last; ++N;
以上是关于Steque 和 API 实现的主要内容,如果未能解决你的问题,请参考以下文章