在 java 中用链表创建 dropout 堆栈的麻烦

Posted

技术标签:

【中文标题】在 java 中用链表创建 dropout 堆栈的麻烦【英文标题】:trouble with making a dropout stack with linked lists in java 【发布时间】:2017-10-07 00:50:23 【问题描述】:

所以在我的作业中,我必须在 Java 中实现一个 dropout 堆栈。退出堆栈在各方面都像堆栈一样,除了如果堆栈大小为 n,那么当 n+1 个元素被压入时,第一个元素会丢失。就我而言,我设置了 n=5。我的代码运行良好,但是当我在第 5 个元素之后添加更多元素时,底部的元素不会被删除。它只是像普通堆栈一样将新堆栈堆叠在顶部。请帮助我了解如何解决此问题。这是我的堆栈实现代码:

/**
 * Represents a linked implementation of a stack.
 *
 * @author Java Foundations 
 * @version 4.0
 */
    public class DropOutStack<T> implements StackADT<T>
    
    private int count; //number of elements in the stack
    private LinearNode<T> top; 

    /*Declares the maximum number of elements in the stack*/
    private final int n = 5;//max size
    private LinearNode<T> prev;
    private LinearNode<T> curr;

    /**
     * Creates an empty stack.
     */
    public DropOutStack()
    
        count = 0;
        top = null;
    

    /**
     * Adds the specified element to the top of this stack.
     * @param element element to be pushed on stack
     */
    public void push(T element)
    
        LinearNode<T> temp = new LinearNode<T>(element);

        /*Verifies that the number of elements in the stack is
         * less than n. If yes, adds the new element to the stack*/
        if (count < n) 
            temp.setNext(top);
            top = temp;
            count++;
        
        /*Verifies if the number of elements in the stack is greater
         * than or equal to n or not, and that the n is not equal to one.
         * If yes, removes the first element from the stack and adds
         * the new element to the stack*/
        else if(count>=n && n!=1) 
            prev = top;
            curr = top.getNext();

            while(curr != null) 
                prev = prev.getNext();
                curr = curr.getNext();
            
            prev.setNext(null);
            count--;

            push(element);
        
        else //if n=1
        
            top.setElement(element);
        
    

    /**
     * Removes the element at the top of this stack and returns a
     * reference to it. 
     * @return element from top of stack
     * @throws EmptyCollectionException if the stack is empty
     */
    public T pop() throws EmptyCollectionException
    
        if (isEmpty())
            throw new EmptyCollectionException("stack");

        T result = top.getElement();
        top = top.getNext();
        count--;

        return result;
    

    /**
     * Returns a reference to the element at the top of this stack.
     * The element is not removed from the stack.  
     * @return element on top of stack
     * @throws EmptyCollectionException if the stack is empty  
     */
    public T peek() throws EmptyCollectionException
    

        if (isEmpty())
            throw new EmptyCollectionException("stack");
        T result = top.getElement();

        return result;

    

    /**
     * Returns true if this stack is empty and false otherwise. 
     * @return true if stack is empty
     */
    public boolean isEmpty()
    
        return (count ==0);

    

    /**
     * Returns the number of elements in this stack.
     * @return number of elements in the stack
     */
    public int size()
    
        return count;
    

    /**
     * Returns a string representation of this stack. 
     * @return string representation of the stack
     */
    public String toString()
    
        String result = "";
        LinearNode<T> current = top;
        while (current != null) 
            result = current.getElement() + "\n" + result;
            current = current.getNext();
        
        return result;
    
    

【问题讨论】:

欢迎来到 Stack Overflow!看来您需要学习使用调试器。请帮助自己一些complementary debugging techniques。如果您之后仍有问题,请随时返回 Minimal, Complete and Verifiable Example 来证明您的问题。 【参考方案1】:

问题是您在 else if (count &gt;= n &amp;&amp; n != 1) 块中的链表上迭代得太远了。

当前你在curr == null 时终止,但如果currnull 那么prev 是列表中的最后一个节点,谁的下一个值已经是null (curr)。

要解决此问题,请将循环条件更改为 curr.getNext() != null。由于您总是想要推送元素,因此只需在最后执行此操作并简化逻辑,前提是 n(最大尺寸 [可怜的名称])应至少为 1。

/**
 * @pre. n >= 1
 */
public void push(T element) 
    if (count >= n) 
        assert top != null;
        prev = null;
        curr = top;
        while (curr.getNext() != null) 
            prev = curr;
            curr = curr.getNext();
        
        if (prev != null) 
            prev.setNext(null);
         else 
            top = null;
        
        count--;
    
    LinearNode<T> temp = new LinearNode<>(element);
    temp.setNext(top);
    top = temp;
    count++;

【讨论】:

@JohnnySack 没问题。对于任何涉及数据结构的工作,有时您能做的最好的事情就是用笔和纸画出结构和动作,这样您就可以直观地看到正在发生的事情。 我有另一个问题。你介意帮我解决吗? @JohnnySack 我建议先尝试自己解决这个问题(也许头脑清醒)。如果您仍然在努力与您的同龄人或导师交谈(假设这也是作业)。作为最后的手段在这里问。最好的学习方法之一是尝试犯错误并找出问题的原因。另外,自己解决问题总能带来更多的满足感!

以上是关于在 java 中用链表创建 dropout 堆栈的麻烦的主要内容,如果未能解决你的问题,请参考以下文章

Java3堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,统计字符个数/斗地主,Collections,异常,线程创建/同步

java:堆栈,队列,枚举,链表

《Java数据结构与算法》笔记-CH5-链表-4用链表实现堆栈

从java中的两个链表堆栈中减去数字

java模拟堆栈,时间类MyDate,字符串链表节点类,类BankCustomer

在 C++ 中使用链表进行堆栈