如何在不获取 NPE 的情况下将节点弹出堆栈

How to pop a Node on a stack without getting a NPE

这是栈的链表实现的pop方法

当 "number of pops" 等于 "size of the linked list" 时,此方法将抛出 NPE。

示例:

LinkedList list = new LinkedList();
        list.push("A");
        list.push("B");
        list.push("C");

        System.out.println(list.pop().getElement());
        System.out.println(list.pop().getElement());
        // the below code list.pop will have a null value.
        System.out.println(list.pop().getElement());
        System.out.println(list.pop().getElement());

public boolean isEmpty()
{
        return head == null;
}

public Node pop()
{

                if( !isEmpty())
                {
                    head = head.getNext();
                    size--;
                }
                else if(isEmpty())
                {
                    System.out.println("empty stack");

                }

                 return  head;

}

我的解决方案是像这样重写,但现在 return 头部有重复的代码,我不知道如何修复。关于此问题的任何指导都会有所帮助。

 public Node pop()
 {

                if(head != null)
                {
                    return head;
                }
                if( !isEmpty())
                {
                    head = head.getNext();
                    size--;
                }
                else if(isEmpty())
                {
                    System.out.println("empty stack");

                }

                 return  head;

 }

另一个问题:不确定,我应该称变量head(链表概念)还是top(堆栈概念)?请也回答这个问题。

我对那些可能想知道为什么我要 return 创建一个稍后将被删除的节点对象的人的论点:我的教科书说 pop 意味着我也需要 return 弹出的节点将其从链接列表中删除,而不是仅仅将其删除。

在方法 pop 中,您没有返回 head,您正在返回 head.getNext()

所以改变你的逻辑。你可以试试这个:

在方法中pop

Node tem = head;
if( !isEmpty())
    {
        head = head.getNext();
        size--;
    }
    else // no need to check head again
    {
        System.out.println("empty stack");

     }

     return  tem;

在您的第一次实施中:

public Node pop()
{
    if( !isEmpty())
    {
        head = head.getNext();
        size--;
    }
    else if(isEmpty())
    {
        System.out.println("empty stack");

    }

     return  head;

}

假设您的列表是 5->6->7->null

头指向5。此列表不为空。所以你做了 head = head.getNext(),现在头指向 6。然后你 return head,也就是 6.

所以您的错误是您没有 return 就跳过了第一个元素。你应该做的是保持对当前头部的引用,前进头部,然后 return 你保存的引用 - 而不是新的 head.


在你的第二个实现中:

public Node pop()
 {
    if(head != null)
    {
        return head;
    }
    if( !isEmpty())
    {
        head = head.getNext();
        size--;
    }
    else if(isEmpty())
    {
        System.out.println("empty stack");

    }

     return  head;

 }

如果 head 不为空,你只是 return,而不推进它。一旦使用 return,方法中将不会执行任何其他操作。


注意:最好不要 return 一个节点,return 与您 push 相同的类型。返回 Node 会使用户危险地访问您的链接列表。您应该 return 使用实际元素。