美文网首页
普林斯顿算法中级笔记3(栈,队列)

普林斯顿算法中级笔记3(栈,队列)

作者: 小白家的小小白 | 来源:发表于2018-07-31 19:22 被阅读0次

    栈,队列

    本节包含了一些基础的数据结构以及他们的实现

    栈(后进先出)

    我们定义栈具有以下方法:

    • push()
    • pop()
    • isEmpty()
    • size()
      栈的链表实现:
      保留指向链表头部(初始位置)的引用,并在该位置增加或删除
      屏幕快照 2018-07-31 下午5.12.23.png
    public class LinkedStackOfStrings
    {
     private Node first = null;
     private class Node
     {
     String item;
     Node next;
     }
    
     public boolean isEmpty()
     { return first == null; }
     public void push(String item)
     {
     Node oldfirst = first;
     first = new Node();
     first.item = item;
     first.next = oldfirst;
     }
     public String pop()
     {
     String item = first.item;
     first = first.next;
     return item;
     }
    }
    

    对上面算法进行复杂度分析;
    算法复杂度:每次增加或删除消耗是恒量
    空间复杂度:这个类所占空间约40N,这个是根据java中每个变量或对象大小来计算的。
    栈的数组实现
    该算法可分为两部分:

    • 元素数量未达到数组长度时的正常的删减
    • 当数组容量不够时对数组的处理,我们重点关注这一种情况
      若是当数组容量达到上限时加一,那么算法复杂度会较高,因为java中数组长度是在初始化时定死的,长度+1意味着对原来数组的全量copy到新数组中。这样的算法复杂度为N2/2。
      下面我们尝试在数组长度的增长方式上做一些改变:
      当数组中元素数量达到上限时,一次性初始化一个两倍长度的新数组,将老数组中数据copy到新数组中
      算法复杂度分析:2+4+8+...+N ~ 3N
      屏幕快照 2018-07-31 下午6.01.10.png
      在达到数组上限时,消耗突然升高。
      那么如果pop()时,要如何处理?当元素数量为长度数组长度一半时减半数组长度? NO,这里有个陷阱,若是恰好在数组填满时,持续push(),pop()那么每次操作都会有最差的算法复杂度N。所以我们在当数组被填充1/4时,将数组长度减半。
      上面实现的空间复杂度:
      8N: 数组满时
      32N:数组被填充1/4时

    栈的两种实现对比:
    链表:每次pop push消耗稳定常量,但需要额外的空间去处理链表结构
    数组:每次pop push消耗可能有很大差别,不过空间复杂度较小

    队列

    队列的链表结构
    我们需要两个引用分别指向队列的头尾,在尾部入队列,头部出队列。

    屏幕快照 2018-07-31 下午5.12.23.png
    public class LinkedQueueOfStrings
    {
     private Node first, last;
    
     private class Node
     { /* same as in StackOfStrings */ }
    
     public boolean isEmpty()
     { return first == null; }
    
     public void enqueue(String item)
     {
     Node oldlast = last;
     last = new Node();
     last.item = item;
     last.next = null;
     if (isEmpty()) first = last;
     else oldlast.next = last;
     }
    
     public String dequeue()
     {
     String item = first.item;
     first = first.next;
     if (isEmpty()) last = null;
     return item;
     }
    } 
    

    本节原文其余部分,讲述了java中的泛型与迭代器,这里不记录。

    相关文章

      网友评论

          本文标题:普林斯顿算法中级笔记3(栈,队列)

          本文链接:https://www.haomeiwen.com/subject/kyzfvftx.html