有人能给我解释一下Java中使用链表的堆栈的以下实现吗?
有人能给我解释一下Java中使用链表的堆栈的以下实现吗?链接如下:代码如下:有人能给我解释一下Java中使用链表的堆栈的以下实现吗?,java,linked-list,stack,Java,Linked List,Stack,有人能给我解释一下Java中使用链表的堆栈的以下实现吗?链接如下:代码如下: public class LinkedStack<Item> implements Iterable<Item> { private int N; // size of the stack private Node first; // top of stack // helper linked list class pri
public class LinkedStack<Item> implements Iterable<Item> {
private int N; // size of the stack
private Node first; // top of stack
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty stack.
*/
public LinkedStack() {
first = null;
N = 0;
assert check();
}
/**
* Is this stack empty?
* @return true if this stack is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns the number of items in the stack.
* @return the number of items in the stack
*/
public int size() {
return N;
}
/**
* Adds the item to this stack.
* @param item the item to add
*/
public void push(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
assert check();
}
/**
* Removes and returns the item most recently added to this stack.
* @return the item most recently added
* @throws java.util.NoSuchElementException if this stack is empty
*/
public Item pop() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
Item item = first.item; // save item to return
first = first.next; // delete first node
N--;
assert check();
return item; // return the saved item
}
/**
* Returns (but does not remove) the item most recently added to this stack.
* @return the item most recently added to this stack
* @throws java.util.NoSuchElementException if this stack is empty
*/
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
return first.item;
}
/**
* Returns a string representation of this stack.
* @return the sequence of items in the stack in LIFO order, separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
/**
* Returns an iterator to this stack that iterates through the items in LIFO order.
* @return an iterator to this stack that iterates through the items in LIFO order.
*/
public Iterator<Item> iterator() { return new ListIterator(); }
// an iterator, doesn't implement remove() since it's optional
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
// check internal invariants
private boolean check() {
if (N == 0) {
if (first != null) return false;
}
else if (N == 1) {
if (first == null) return false;
if (first.next != null) return false;
}
else {
if (first.next == null) return false;
}
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
return true;
}
/**
* Unit tests the <tt>LinkedStack</tt> data type.
*/
public static void main(String[] args) {
LinkedStack<String> s = new LinkedStack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + " ");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}
公共类LinkedStack实现Iterable{
private int N;//堆栈的大小
私有节点优先;//堆栈顶部
//助手链表类
私有类节点{
私人物品;
私有节点下一步;
}
/**
*初始化空堆栈。
*/
公共LinkedStack(){
第一个=空;
N=0;
断言检查();
}
/**
*这个堆栈是空的吗?
*@如果此堆栈为空,则返回true;否则返回false
*/
公共布尔值为空(){
返回first==null;
}
/**
*返回堆栈中的项数。
*@返回堆栈中的项目数
*/
公共整数大小(){
返回N;
}
/**
*将该项添加到此堆栈。
*@param item要添加的项
*/
公共作废推送(项目){
节点oldfirst=第一个;
第一个=新节点();
first.item=项目;
first.next=oldfirst;
N++;
断言检查();
}
/**
*删除并返回最近添加到此堆栈的项。
*@返回最近添加的项目
*如果此堆栈为空,则@throws java.util.NoSuchElementException
*/
公共物品{
如果(isEmpty())抛出新的NoTouchElementException(“堆栈下溢”);
Item=first.Item;//保存要返回的项
first=first.next;//删除第一个节点
N--;
断言检查();
return item;//返回保存的项
}
/**
*返回(但不删除)最近添加到此堆栈的项。
*@返回最近添加到此堆栈的项目
*如果此堆栈为空,则@throws java.util.NoSuchElementException
*/
公共项目peek(){
如果(isEmpty())抛出新的NoTouchElementException(“堆栈下溢”);
返回第一个项目;
}
/**
*返回此堆栈的字符串表示形式。
*@按后进先出顺序返回堆栈中的项目序列,以空格分隔
*/
公共字符串toString(){
StringBuilder s=新的StringBuilder();
用于(项目:本)
s、 追加(项目+“”);
返回s.toString();
}
/**
*返回此堆栈的迭代器,该迭代器按后进先出顺序遍历项。
*@向该堆栈返回一个迭代器,该迭代器按后进先出顺序遍历项目。
*/
公共迭代器迭代器(){返回新的ListIterator();}
//迭代器不实现remove(),因为它是可选的
私有类ListIterator实现了迭代器{
私有节点电流=第一;
公共布尔值hasNext(){返回当前值!=null;}
public void remove(){抛出新的UnsupportedOperationException();}
公共项目下一步(){
如果(!hasNext())抛出新的NoSuchElementException();
项目=当前项目;
当前=当前。下一步;
退货项目;
}
}
//检查内部不变量
私有布尔检查(){
如果(N==0){
if(first!=null)返回false;
}
else如果(N==1){
if(first==null)返回false;
if(first.next!=null)返回false;
}
否则{
if(first.next==null)返回false;
}
//检查实例变量N的内部一致性
int numberOfNodes=0;
for(节点x=first;x!=null;x=x.next){
numberOfNodes++;
}
如果(numberOfNodes!=N)返回false;
返回true;
}
/**
*单元测试LinkedStack数据类型。
*/
公共静态void main(字符串[]args){
LinkedStack s=新LinkedStack();
而(!StdIn.isEmpty()){
String item=StdIn.readString();
如果(!item.equals(“-”)s.push(item);
如果(!s.isEmpty())StdOut.print(s.pop()+);
}
StdOut.println(“(“+s.size()+”堆栈上的左侧)”;
}
}
除了需要使用check()
方法外,所有内容都很清楚。我不明白的是,为什么在每次操作(即pop
,peek
)之后,我们需要检查堆栈中元素的数量和变量N
(堆栈的大小)的一致性。我们不是一直保持这两个价值观一致吗?我真的看不出check()
方法有什么用?上面的check()
方法只在中使用
断言可以提供对预期不变量的实时检查。默认情况下,它们被禁用
通常在开发环境中,您可以使用check()方法来检测错误或调试。check()方法是不需要的。它仅用于断言,在生产环境中是不需要的。