带圆形阵列问题的Deque实现

时间:2018-02-02 02:39:22

标签: java arrays queue deque

我正在尝试完全实现Deque而不使用已在java库中创建的Deque。我的代码编译,但输出并不像预期的那样。例如,应该将容量作为参数提供给类,但结果表明实际容量最终比指定的数量低1。

我遇到的另一个问题是队列应该作为先进先出。但这没有在结果中体现出来。任何想法?

public class ArrayDeque<E> implements IDeque<E> {


    private int capacity;
    private E[] array;
    private int front;
    private int end;
    private int size;


    public ArrayDeque(int capacity) {

        this.array = (E[]) new Object[capacity];
        this.capacity = capacity - 1;
        front = 1;
        end = 0;
        size = 0;


    }


    private boolean isFull() {
        return (size == capacity);
    }


    private boolean isEmpty() {
        return (size == 0);
    }


    @Override
    public int size() {
        return size;
    }


    @Override
    public void addFirst(E elem) throws DequeFullException {
        if (isFull())
            throw new DequeFullException("samlingen er full!");
        array[front] = elem;
        front = (front + 1) % capacity; // use modulo to make sure the front restarts from initial position once it reaches capacity
        size++;
    }

    @Override
    public E pullFirst() throws DequeEmptyException {
        if (isEmpty())
            throw new DequeEmptyException("Samlingen er tom!");
        front = (front - 1) % capacity;
        size--;
        return array[front];
    }


    @Override
    public E peekFirst() throws DequeEmptyException {
        if (isEmpty())
            throw new DequeEmptyException("samlingen er tom!");

        System.out.println(array[(front - 1) % capacity]);
        return array[(front - 1) % capacity];
    }

    @Override
    public void addLast(E elem) throws DequeFullException {
        if (isFull())
            throw new DequeFullException("samlingen er full!");
        array[end] = elem;
        end = (end - 1) % capacity;
        size++;

    }

    @Override
    public E pullLast() throws DequeEmptyException {
        if (isEmpty())
            throw new DequeEmptyException("samlingen er tom!");
        end = (end + 1) % capacity;
        size--;
        return array[end];


    }


    @Override
    public E peekLast() throws DequeEmptyException {
        if (isEmpty())
            throw new DequeEmptyException("samlingen er tom!");
        System.out.println(array[(end + 1) % capacity]);
        return array[(end + 1) % capacity];
    }

}
public class Main {
    public static void main(String[] args){
    ArrayDeque<String> deque = new ArrayDeque<>(6);

    deque.addFirst("first");
    deque.addFirst("second");
    deque.addFirst("third");
    deque.addFirst("fourth");


    deque.peekFirst();
    deque.peekLast();
    deque.addLast("fourth");
    deque.addLast("last");
    deque.peekLast();
    deque.size();
    }
}

1 个答案:

答案 0 :(得分:1)

关于您遇到的容量问题: 您正在设置阵列以使用户传递容量。这意味着例如用户输入6。现在,您将内部容量设置为容量-1,这意味着它将为5.现在,如果您使用较低容量执行模数,它会将位置设置为0,即使它可以在技术上将某些内容放入array[5] 。这是使用Arrays.toString运行的程序的打印,在每个addFront()之后打印您的数组:

[null, 0, null, null, null, null]
0
[null, 0, 1, null, null, null]
0
[null, 0, 1, 2, null, null]
0
[null, 0, 1, 2, 3, null]
0
[4, 0, 1, 2, 3, null]
0
[4, 5, 1, 2, 3, null]
5

这个问题的解决方案相当简单。将构造函数设置为如下所示:

public ArrayDeque(int capacity) {

    this.array = (E[]) new Object[capacity];
    this.capacity = capacity;
    front = 1;
    end = 0;
    size = 0;
}

此外,考虑到您的FiFo问题: 您可能需要考虑更好地跟踪最后添加的元素以及应返回的元素。这可能会引入两个新的变量,但会让你的生活变得更加容易。例如:

public void addFirst(E elem) throws DequeFullException {
    if (isFull())
        throw new DequeFullException("samlingen er full!");
    array[front] = elem;
    first = front;
    front = (front + 1) % (capacity); // use modulo to make sure the front restarts from initial position once it reaches capacity]
    size++;
    System.out.println(Arrays.toString(array));
}

假设first是一个整数,在构造函数中设置为0。你可以随心所欲地做到这一点,但这可以更好地跟踪你的第一个元素。

另外,你的方法有点问题,考虑到你在一些数组中向后遍历一个数组,而没有考虑ArrayOutOfBoundsException为-1的可能性。要解决这个问题,您可能希望从[0]的结尾和[1]的结尾切换到中间的起点。你必须找到一种放置和返回正确位置的方法,也许检查你用于遍历的变量是否等于0以及它是否转到数组的另一侧。像这样:

public E pullFirst() throws DequeEmptyException {
    if (isEmpty())
        throw new DequeEmptyException("Samlingen er tom!");
    if(front == 0)
        front = capacity;
    front = (front-1) % (capacity);
    size--;
    return array[front];
}

使用main()中的代码生成以下输出:

public class Main {
    public static void main(String[] args) {
        ArrayDeque<Integer> arrDq = new ArrayDeque<>(6);

        for(int i = 0; i < 6; i ++)
        {
            arrDq.addFirst(i);
        }
        for(int i = 0; i < 6; i ++)
        {
            System.out.println(arrDq.pullFirst());
        }
    }
}

输出:

[null, 0, null, null, null, null]
[null, 0, 1, null, null, null]
[null, 0, 1, 2, null, null]
[null, 0, 1, 2, 3, null]
[null, 0, 1, 2, 3, 4]
[5, 0, 1, 2, 3, 4]
5
4
3
2
1
0

为Deque的后部做同样的事情,它应该工作得很好。我希望这会有所帮助。