先进先出队列-《算法》(第四版)学习笔记

在1.3节有关“背包、队列和栈”的学习中发现了算法1.3代码中有两行略微费解,而书中对此并无明确解释:

import edu.princeton.cs.algs4.StdOut;

public class Queue<T> {
    private int N;
    private Node first;
    private Node last;
    private class Node{
        T item;
        Node next;
    }
    public boolean isEmpty(){
        return N==0;
    }
    public int size(){
        return N;
    }
    public void enqueue(T item){
        Node oldlast=last;
        last=new Node();
        last.item=item;
        if (isEmpty()) first=last; //①
        else oldlast.next=last;
        N++;
    }
    public T pop(){
        T item=first.item;
        first=first.next;
        if (isEmpty()) last=null;//②
        N--;
        return item;
    }
    public static void main (String[] args){
        Queue<String> q=new Queue<>();
        q.enqueue("hello");
        q.enqueue("hell");
        StdOut.println(q.pop());
        StdOut.println(q.pop());
        StdOut.println(q.last.item);

  }
} 

在后续的测试中我发现,①与②的判断逻辑是紧密关联的。先说enqueue方法:

由于first和last的默认值都是null,当last被初始化后,first的值仍然是null,此时first中item为空,next亦无指向。若不加上isEmpty判断的话,第一次调用enqueue方法后立即调用pop方法会引发NullPointerException。显然在节点中已经赋予一个有效值的情况下出现这种状况既不符合逻辑,更不是我们想要的。由pop方法的调用,我们看到是first值为null造成的,既然此时节点中已经有一个值(这个值被赋予了last)了,那自然是first=last;

而对于②,测试代码的最后一行显示,在队列弹出最后一个元素是,由于first=first.next, first.next的指向null(这没问题),但是first为空了,表明队列中已经没有元素了,可是此时last仍然持有原有的引用,依然可以用last.item访问到内容。这是不应该的,故而当判断isEmty为真后,last=null;是必须的。

另外再吐槽一下80页Dijkstra双栈算术表达式求值法,作者使用这个算法为例也许是为了让读者更好地理解栈的运用。不过这个示例本身有两点缺陷:1、只能用来计算非常严格的带有括号的表达式的值,这里的严格指的是(1+2+3)这样的表达式是计算不出来的,只能写成(1+(2+3))。2、在控制台输入表达式的时候必须加空格,比如(1+(2+3))这样是计算不出来的,只能写成( 1 + ( 2 + 3 ) )。

转载于:https://www.cnblogs.com/olin/p/10074873.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值