Data Structures (四) - 队列Queue实现(三)

简介: Data Structures (四) - 队列Queue实现

增加扩容方法

private void expansionCapacity(int newCapacity){
    int oldCapacity = elements.length;
    if (oldCapacity >= size + 1) return;
    // 创建一个新的容量的数组
    // newCapacity = oldCapacity + (oldCapacity >> 1);
    T[] newElements = (T[]) new Object[newCapacity];
    // 拷贝元素
    for (int i = 0; i < size; i++) {
        newElements[i] = elements[(i + front) % elements.length];
    }
    // 指向新的内存空间
    elements = newElements;
    front = 0;
    System.out.println("扩容成功,由" + oldCapacity + "扩展至" + newCapacity);
}
复制代码

修改enQueue方法代码

public void enQueue(T element){
    expansionCapacity(elements.length + (elements.length >> 1));
    elements[(front + size) % elements.length] = element;
    size++;
}
复制代码

扩容测试代码

@Test
public void testExpansion() {
    queue.deQueue();
    System.out.println(queue);
    for (int i = 0; i < 3; i++) {
        queue.enQueue(i);
    }
    System.out.println(queue);
    for (int i = 0; i < 3; i++) {
        queue.deQueue();
    }
    System.out.println("After deQueue: " + queue);
    for (int i = 0; i < 4; i++) {
        queue.enQueue(i + 100);
    }
    System.out.println("After enQueue: " + queue);
    for (int i = 0; i < 8; i++) {
        queue.deQueue();
    }
    System.out.println(queue);
}
复制代码

执行测试

db73a6ee768e414391199421eca9bf67_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

五、循环双端队列

可以在两端进行添加、删除操作的循环队列

新建一个CircleDeque

public class CircleDeque<T> {
    private int front;
    private int size;
    private T[] elements;
    public static final int DEFAULT_CAPACITY = 10;
    // 构造函数,定义数组的长度
    public CircleDeque(){
        elements = (T[]) new Object[DEFAULT_CAPACITY];
    }
    public int size(){
        return size;
    }
    public boolean isEmpty(){
        return size == 0;
    }
    public void clear(){
        for (int i = 0; i < elements.length; i++) {
            elements[index(i)] = null;
        }
        size = 0;
        front = 0;
    }
    public int index(int index){
        return (front + index) % elements.length;
    }
    private void expansionCapacity(int newCapacity){
        int oldCapacity = elements.length;
        if (oldCapacity >= size + 1) return;
        // 创建一个新的容量的数组
        // newCapacity = oldCapacity + (oldCapacity >> 1);
        T[] newElements = (T[]) new Object[newCapacity];
        // 拷贝元素
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[(i + front) % elements.length];
        }
        // 指向新的内存空间
        elements = newElements;
        front = 0;
        System.out.println("扩容成功,由" + oldCapacity + "扩展至" + newCapacity);
    }
    @Override
    public String toString() {
        return "CircleQueue{" +
                "front=" + front +
                ", size=" + size +
                ", elements=" + Arrays.toString(elements) +
                '}';
    }
}    
复制代码

获取头部和尾部的元素

public T front(){
    return elements[front];
}
public T rear(){
    return elements[index(front + size - 1)];
}
复制代码

从尾部入队和从头部移除与双端队列的方法一致

// 从尾部入队
public void enQueueRear(T element){
    expansionCapacity(elements.length + (elements.length >> 1));
    elements[(front + size) % elements.length] = element;
    size++;
}
// 从头部出队
public T deQueueFront(){
    // 先获取对头的元素
    T frontEle = elements[front];
    // 将对头的元素置为空
    elements[front] = null;
    // 队头要往后移动一次
    // front++;
    front = (front + 1) % elements.length;
    // 长度-1
    size--;
    // 返回队头元素
    return frontEle;
}
复制代码

从头部入队时,如果front是0,那么插入的位置是-1,数组中不存在-1的索引,使用-1 + 数组长度就可以变成真正数组中的索引,index方法需要增加判断

public int index(int index){
    index += front;
    if (index < 0){
        return index + elements.length;
    }
    return (front + index) % elements.length;
}
复制代码

从尾部出队和从头部入队方法实现

// 从尾部出队
public T deQueueRear(){
    // 获取真实索引
    int rearIndex = index(size - 1);
    T rear = elements[rearIndex];
    elements[rearIndex] = null;
    size--;
    return rear;
}
// 从头部入队
public void enQueueFront(T element){
    expansionCapacity(elements.length + (elements.length >> 1));
    front = index(front - 1);
    elements[front] = element;
    size ++;
}
复制代码

新增测试类

public class CircleDequeTest {
    CircleDeque<Integer> deque = null;
    @Before
    public void init(){
        deque = new CircleDeque<>();
        for (int i = 0; i < 8; i++) {
            deque.enQueueRear(i + 10);
        }
        System.out.println("After Init" + deque);
    }
    @Test
    public void front() {
        System.out.println("CircleDeque Front: " + deque.front());
    }
    @Test
    public void rear() {
        System.out.println("CircleDeque Rear: " + deque.rear());
    }
    @Test
    public void enQueueRear() {
        deque.enQueueRear(18);
        System.out.println("After enQueueRear:" + deque);
    }
    @Test
    public void deQueueFront() {
        deque.deQueueFront();
        System.out.println("After deQueueFront: " + deque);
    }
    @Test
    public void deQueueRear() {
        deque.deQueueRear();
        System.out.println("After deQueueRear: " + deque);
    }
    @Test
    public void enQueueFront() {
        deque.enQueueFront(9);
        System.out.println("After enQueueFront: " + deque);
    }
}
复制代码

执行测试

869aca2036374b89b108d515ac068a6b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


相关文章
|
存储
LeetCode 232. Implement Queue using Stacks
使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部。 pop() -- 从队列首部移除元素。 peek() -- 返回队列首部的元素。 empty() -- 返回队列是否为空。
78 0
LeetCode 232. Implement Queue using Stacks
LeetCode 225. Implement Stack using Queues
使用队列实现栈的下列操作: push(x) -- 元素 x 入栈; pop() -- 移除栈顶元素; top() -- 获取栈顶元素; empty() -- 返回栈是否为空
82 0
LeetCode 225. Implement Stack using Queues
Data Structures (四) - 队列Queue实现(二)
Data Structures (四) - 队列Queue实现
Data Structures (四) - 队列Queue实现(二)
The LinkQuNode for Linked queue (Continuous updates) | Data
The code in Data book (5th Edition) from the 105 page to 106 page
95 0
Data Structures (二) - 链表LinkedList实现(Part B)
Data Structures (二) - 链表LinkedList实现(Part B)
Data Structures (二) - 链表LinkedList实现(Part B)
|
存储 索引
Data Structures | 连载 02 - 链表 LinkedList 实现(上)
Data Structures | 连载 02 - 链表 LinkedList 实现
Data Structures | 连载 02 - 链表 LinkedList 实现(上)
|
存储 索引
Data Structures | 连载 02 - 链表 LinkedList 实现(下)
Data Structures | 连载 02 - 链表 LinkedList 实现
Data Structures | 连载 02 - 链表 LinkedList 实现(下)
Data Structures (三) - 栈Stack实现
Data Structures (三) - 栈Stack实现
Data Structures (三) - 栈Stack实现
|
机器学习/深度学习
Data Structures (五) - 二叉树Binary Tree
Data Structures (五) - 二叉树Binary Tree
Data Structures (五) - 二叉树Binary Tree