Proj1a 数据结构:双端队列| CS61B-Spring-2018

主要任务

编写双端队列,能够addFirst, remove First, addLast, removeLast.并实现其他一些辅助功能。

使用两种数据结构来完成双端队列,分别是链表和数组。
要求这两种数据结构的add和remove操作都花费O(1)的时间,即与队列长度无关。

LinkedListDeque

主要思路见Week2中的双向链表。主要思路是:

  • 循环链表与哨兵节点:在双向链表中设置一个哨兵节点,它的next永远指向第一个节点,pre永远指向最后一个节点(即使此时链表为空,只有它自己,那么next和pre就都指向自己)。

较为顺利,因为实现的结构与双向链表非常相似。

但递归实现get时,稍微遇到了一点问题,最后添加了一个辅助方法:

    public T getRecursive(int index) {
        if (index > size - 1) {
            return null;
        }
        return getR(sentinel.next, index);
    }

    private T getR(ItemNode l, int i) {
        if (i == 0) {
            return l.item;
        }
        return getR(l.next, i - 1);
    }

getRecursive这个方法肯定不是递归的,因为传参不传ItemNode,根本没法找到剩下的,所以要添加一个传了ItemNode的方法。

ArrayDeque

这个真是想到头秃…………核心思路有两个点:

  • 循环数组:一开始,令数组中任意两个相邻的节点为nextfirst和nextlast,将数组以这两个中心向两端扩展,遇到头就回到尾部,遇到尾就回到头部。
    详细图示说明(科学上网)

  • 处理循环数组中的索引:将双端队列中数的下一个数的位置映射到实际的数组中。例如,这一个数索引为items.length-1(即数组最后),则下一个数应该位于0位置.若索引还不到最后一位,则下一个数的位置就是下一个数的索引,正常+1即可。
    这个trick应该很常用于循环。每次将索引+1,一到某个阈值 就从头开始。
    也不一定是+1,可以+任意值,总之处理循环数据结构的索引也许可以这么用。

    private int addOne(int a) {
        return (a + 1) % items.length;
    }
    private int subOne(int a) {
        return (a - 1 + items.length) % items.length;
    }
    
    类似地,在get时,也可以使用这个思想:
    int start = addOne(nextfirst);
    return items[(start + index) % items.length];

编写中的问题

“Raw use of parameterized class”

Proj1a 数据结构:双端队列| CS61B-Spring-2018_第1张图片

  • 原理:
    java Generic Type/Parameterized Type/Raw Type
    What Is a Generic Type? A generic type is a generic class or interface that uses type parameters.(即SLList< T >这个类。)
    What Is a Parameterized Type? A parameterized type is a parameterized version of a generic class or interface. For example, Vector< String > is a parameterized type.(SLList< T >这种类型就是一个Parameterized Type。)
    What Is a Raw Type? A raw type is a parameterized type with the parameter type argument omitted. For example, Vector is raw type.(SLList不带< T >就是一个raw type)
    Java其实是支持只用raw type的,但是会警告。

  • 修改方法:将嵌套类的声明改为public class ItemNode,去掉< T >和static。(去掉static的原因是,让嵌套类内部的T访问到外部< T >,知道这是个泛型。)
    而去掉的原因是,之前ItemNode类被声明为ItemNode< T >,后面用它的时候却只用了ItemNode,所以会警告。

除法

想要表达size/items.length<0.25,即使是(double)size/items.length<0.25也不行,只能:size < (items.length / 4)

提交的一些错误

  • 格式:运算符前后空格、if要用{}、{前面要有空格
  • 嵌套类、实例变量private
  • 注意队列为空还要delete的情况

最终
github地址
Proj1a 数据结构:双端队列| CS61B-Spring-2018_第2张图片
还是有些地方没有加空格这种格式错误,懒得改了…

你可能感兴趣的:(CS61B)