Java 在用户定义的LinkedList中创建推送和弹出方法

Java 在用户定义的LinkedList中创建推送和弹出方法,java,linked-list,stack,Java,Linked List,Stack,最近,我们班一直在学习ArrayList和LinkedList。上周我们收到一份作业,要求我们在LinkedList堆栈类中创建push和pop方法。我理解堆栈背后的逻辑,因此它是后进先出的,但我在实际代码方面遇到了问题。我对计算机科学相当陌生(这是我有史以来的第二门课程),而这项特殊的作业真的让我毛骨悚然。我已经交了这项作业,但下周我们有期中考试,我想把它做好。我一直在网上和我的课本上寻找帮助,但什么也没有。我的教授只让我参考助教,助教只关心帮助我理解逻辑,而不是实际的代码。我将在下面发布我的

最近,我们班一直在学习ArrayList和LinkedList。上周我们收到一份作业,要求我们在LinkedList堆栈类中创建push和pop方法。我理解堆栈背后的逻辑,因此它是后进先出的,但我在实际代码方面遇到了问题。我对计算机科学相当陌生(这是我有史以来的第二门课程),而这项特殊的作业真的让我毛骨悚然。我已经交了这项作业,但下周我们有期中考试,我想把它做好。我一直在网上和我的课本上寻找帮助,但什么也没有。我的教授只让我参考助教,助教只关心帮助我理解逻辑,而不是实际的代码。我将在下面发布我的教授给我的说明,以及到目前为止我的代码。提前谢谢

来自教授:

使用以下Java代码中给出的模板实现堆栈 档案:

CS401StackInterface.java CS401StackLinkedListImpl.java

public interface CS401StackInterface<E>
{
   /**
    * Get the top element on the stack.
    * 
    * @return the first element on the stack.
    */
   public E pop();

   /**
    * Adds an element on the top of the stack.
    * 
    * @param e - The element to be added to the stack.
    */
   public void push(E e);

   /**
    * Determines the number of elements in this data structure.
    * 
    * @return the number of elements currently resident in this
    *         data structure.
    */
   public int size();
}
我遇到的一切都告诉我创建一个新的堆栈,这很容易,因为这样我就不必担心代码的“内部”,但这不是我需要的。谢谢

public void push(E e)
看起来还可以

public E pop()
它似乎不正常:您分配给
头。接下来
元素本身,这将创建一个循环。然后返回实际的
。您应该首先将当前头保存到某个位置,然后更新对下一个元素的引用,并返回上一个头

public int size()

方法是错误的:首先,您将一个无用的元素实例化为
temp
,但您不需要它(因为您将在循环内使用temp,并且您应该将其初始化为当前的
head
。然后检查您的for循环:您正在停止条件下或循环迭代结束时使用
head
。您不应该使用
head
,因为您只是在列表上迭代,而不是修改它,只是
>temp
(检查您的
toString
代码是否正确)。

查看代码,您的Pop方法似乎是反向的

在push方法中,您将当前head元素分配给新LinkEntry的“next”属性,然后将其作为新head。因此,当您从列表中弹出项目时,您需要将“next”元素重新分配给列表的head。因此,您的代码是:

head.next = head;
应该是:

LinkEntry<E> toReturn = head;
head = head.next;
return toReturn.element;
LinkEntry toReturn=head;
head=head.next;
返回toReturn.element;

实际上,您正在将head引用克隆到堆栈顶部的当前项(以便可以返回它),然后移动head引用以指向堆栈中的下一项。问题在于
size
方法。它会损坏
head
的值,使其为
null
。然后对
pop
的调用将获得NPE

变量初始化也有问题-
num\u元素
在每次调用
size
时都会增加。您可以通过在调用
push
时增加变量来简化此过程

此外,如果使用
setElement
,也会损坏堆栈,因为它只设置
,而不修补下一个指针

抱歉,我看到这是交给作业的…所以这里有一些具体的方法来更正代码:

public CS401StackLinkedListImpl()
{
    head = null;
    num_elements = 0;
}

public void setElement(LinkEntry<E> anElement)
{
    if (head != null)
        anElement.next = head.next; //New top-of-stack needs to point to next element, if any
    else
        anElement.next = null;
    head = anElement;
}

/*Append the new element to the end of the list*/
public void push(E e)
{
    LinkEntry<E> temp = new LinkEntry<E>();
    temp.element = e;
    temp.next = head;
    head = temp;

    num_elements++; // Increase number of elements count here
}

/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
    E result = head.element; // Save return value of TOS
    head = head.next; // Corrected POP action
    num_elements--;
    return result;
}

public int size()
{
    //Remove below since count is kept accurate with push/pop methods
    //LinkEntry<E> temp = new LinkEntry<E>();
    //for (temp = head; head != null; head = head.next)
    //    num_elements++;
    return num_elements;
}
/*将新元素追加到列表的末尾*/
公共空间推送(E)
{
LinkEntry temp=新的LinkEntry();
温度元素=e;
下一个温度=压头;

num_elements++;//Increment count您的
NullPointerException
位于第30行,但是您粘贴了代码段,没有使用包或导入。第30行是哪一行?我还建议您在推送方法中使用num_elements+。这样,您就可以始终知道堆栈中有多少个元素,这样您的size方法就可以返回num_elem不需要尝试计算。@user1723905.实际上你做得很好。.如果这是你的第二门课程..看起来你做得很好。你使用的是什么开发环境?不管是什么,我强烈建议你学习如何使用现有的调试工具。这将让你了解变量的值在你的代码中添加参数,帮助你找出问题所在。
size
不会初始化
num\u元素
,所以它会继续增加。实际上,num\u元素应该在
push
中增加,然后
size
将返回值。实际上,这是因为
head
用于
size
他们得到了NPE,因为在那次呼叫之后,
被损坏了。是的,这就是原因,但我的答案更广泛,只是为了让他做正确的事情并理解原因。实际上,这本身并不是家庭作业……它最初是基于家庭作业,但他已经交了作业。这只是为了利尔尼NG。不知道这是否会改变你的答案,但它似乎值得一提。这个答案是很好的,所以我已经投票赞成了。还有几件事:不要忘记更新StEntEngEnter()中的NUMILE元素;也可以考虑将这个方法重命名为Sethe Adter()以更具体;你也可以在Studio()中重用它。。如果您仍然觉得值得保留此方法,请执行所有这些操作。我个人不认为它有什么用处。@Zecc,实际上
num\u elements
不应在
setElement
(或
setHead
)中更改因为堆栈的大小没有改变。@KevinBrock谢谢你的帮助!这是我第一次在这个网站上发布,我没想到会这么快收到帮助,我真的很感激。虽然我已经交了作业,但我对下周的考试感觉好多了。
num_elements
肯定会改变当
head==null
时,它应该变为1。
num\u元素
head.next = head;
LinkEntry<E> toReturn = head;
head = head.next;
return toReturn.element;
public CS401StackLinkedListImpl()
{
    head = null;
    num_elements = 0;
}

public void setElement(LinkEntry<E> anElement)
{
    if (head != null)
        anElement.next = head.next; //New top-of-stack needs to point to next element, if any
    else
        anElement.next = null;
    head = anElement;
}

/*Append the new element to the end of the list*/
public void push(E e)
{
    LinkEntry<E> temp = new LinkEntry<E>();
    temp.element = e;
    temp.next = head;
    head = temp;

    num_elements++; // Increase number of elements count here
}

/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
    E result = head.element; // Save return value of TOS
    head = head.next; // Corrected POP action
    num_elements--;
    return result;
}

public int size()
{
    //Remove below since count is kept accurate with push/pop methods
    //LinkEntry<E> temp = new LinkEntry<E>();
    //for (temp = head; head != null; head = head.next)
    //    num_elements++;
    return num_elements;
}
if (head == null)
    throw new StackUnderflowException(); // and define a StackUnderflowException; or use a standard exception with a message
/*Append the new element to the end of the list*/
public void push(E e)
{
    LinkEntry<E> temp = new LinkEntry<E>();
    temp.element = e;
    temp.next = head;
    num_elements++;//Increment count<--- Correction
    head = temp;
}

/*Remove the most recently pushed element at the end of the list*/
public E pop()
{
    E returnValue =head.element ;<--- Correction
    head=head.next;<--- Correction
    num_elements--;//Decrement count
    return  returnValue;
}

public int size()
{
   return num_elements;<--- Correction
}