数据结构和算法学习笔记之 04. 对基于数组实现环形队列的一个升级实现

基于数组实现环形队列

该方式需要预留一个空间

package com.tomdd.structure.arrayqueue;

/**
 * 

循环数组实现队列

* 预留了一个空位置,也就是说maxSize = 4,其实只能存放3个元素 * * @author zx * @date 2022年12月25日 0:01 */
public class CircleArrayQueue { /** * real表示队列最后一个元素的后一个位置(约定希望空出一个空间),初始值也是为0 */ private int real; /** * front表示队列第一个元素,默认值为0 */ private int front; /** * 存放队列元素的数组 */ private int[] arr; /** * 假设队列最大容量,其实真实存放个数: hypothesisMaxSize -1 */ private int hypothesisMaxSize; public CircleArrayQueue(int hypothesisMaxSize) { this.hypothesisMaxSize = hypothesisMaxSize; arr = new int[hypothesisMaxSize]; } private void isFull() { if ((real + 1) % hypothesisMaxSize == front) { throw new RuntimeException("队列已满"); } } private void isEmpty() { if (real == front) { throw new RuntimeException("队列为空"); } } public void push(int num) { isFull(); arr[real] = num; real = (real + 1) % hypothesisMaxSize; } public int poll() { isEmpty(); int value = arr[front]; front = (front + 1) % hypothesisMaxSize; return value; } public int size() { return (real + hypothesisMaxSize - front) % hypothesisMaxSize; } public void printQueue() { isEmpty(); for (int i = front; i < front + size(); i++) { System.out.printf("arr[%d]=%d\n", i % hypothesisMaxSize, arr[i % hypothesisMaxSize]); } } }

稍微改进了一下

指定数量,队列中就存放改数量的元素个数,但是还设有有一个缺陷,后面再继续改进

package com.tomdd.structure.arrayqueue;

import com.tomdd.exception.GraceException;

/**
 * 环形队列
 *
 * @author zx
 * @date 2022年12月25日 19:14
 */
public class CircleQueue {
    //TODO 思考: 如果不预留一个位置了。real都表示最后一个位置了?????
    /**
     * 取出元素的下标
     */
    private int front;

    /**
     * 存放元素的下标
     */
    private int real;

    /**
     * 存放元素的下标
     */
    private final int[] arr;

    /**
     * 队列的容量
     */
    private final int capacity;

    public CircleQueue(int capacity) {
        this.capacity = capacity + 1;
        this.arr = new int[this.capacity];
    }

    /**
     * @return 队列是否为空
     */
    private boolean isEmpty() {
        return real == front;
    }

    /**
     * @return 队列是否已满
     */
    private boolean isFull() {
        return (real + 1) % capacity == front;
    }

    /**
     * @return 队列里面有效的元素个数
     */
    public int size() {
        return (real + capacity - front) % capacity;
    }

    /**
     * 添加元素到队列中
     *
     * @param num 添加的元素
     */
    public void add(int num) {
        if (isFull()) {
            GraceException.display("队列已满");
        }
        arr[real] = num;
        real = (real + 1) % capacity;
    }

    public int get() {
        if (isEmpty()) {
            GraceException.display("队列为空");
        }
        int temp = arr[front];
        front = (front + 1) % capacity;
        return temp;
    }

    /**
     * 打印队列里面的有效个数
     */
    public void items() {
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]=%d\n", i % capacity, arr[i % capacity]);
        }
    }

    /**
     * 打印队列里面真实的元素情况
     */
    public void printRealArray() {
        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d]=%d\n", i, arr[i]);
        }
    }

}

单元测试

package com.tomdd.structure;

import com.tomdd.structure.arrayqueue.CircleQueue;
import com.tomdd.structure.arrayqueue.ArrayQueue;
import com.tomdd.structure.arrayqueue.CircleArrayQueue;
import org.junit.Test;

/**
 * 

基于数组实现队列先进先出

* * @author zx * @date 2022年12月24日 23:40 */
public class ArrayQueueTest { /** *

测试数组实现队列先进先出效果

* 改方式不能重复添加没有改变指针的引用 */
@Test public void testArrayQueue() { ArrayQueue queue = new ArrayQueue(3); queue.add(1); queue.add(2); queue.add(3); System.out.println(queue.getQueue()); System.out.println(queue.getQueue()); //queue.add(4); System.out.println(queue.getQueue()); } /** *

循环数组

* 循环数组实现队列取出数据后可以再存放数据 * 环形算法 ----负载均衡 */
@Test public void circleArrayQueue() { CircleArrayQueue queue = new CircleArrayQueue(5); queue.push(1); queue.push(2); queue.push(3); queue.push(4); queue.printQueue(); System.out.println("------------------"); System.out.println(queue.poll()); System.out.println(queue.poll()); System.out.println(queue.poll()); System.out.println(queue.poll()); queue.push(5); queue.push(6); queue.push(7); queue.push(8); queue.printQueue(); System.out.println("-------------------"); System.out.println(queue.poll()); queue.push(9); queue.printQueue(); } /** * 测试队列添加元素个数和传递的容量数量一直和打印队列元素 */ @Test public void testCircleQueueAndItems() { CircleQueue queue = new CircleQueue(3); queue.add(1); queue.add(2); queue.add(3); queue.items(); System.out.println("打印队列里面真实的情况:"); queue.printRealArray(); } /** * 测试多次从队列中获取和添加元素 */ @Test public void testGetCircleQueue() { CircleQueue queue = new CircleQueue(3); queue.add(1); queue.add(2); queue.add(3); queue.items(); System.out.println("从队列中取出数据:"+queue.get()); System.out.println("取出数据后再添加元素进行打印:"); queue.add(4); queue.items(); System.out.println("从队列中取出数据:"+queue.get()); System.out.println("从队列中取出数据:"+queue.get()); System.out.println("从队列中取出数据:"+queue.get()); queue.add(5); queue.add(6); queue.add(7); System.out.println("队列里面元素个数:"+queue.size()); queue.items(); System.out.println("队列里面真实的数组打印:"); queue.printRealArray(); System.out.println("从队列中取出数据:"+queue.get()); System.out.println("从队列中取出数据:"+queue.get()); System.out.println("打印队列:"); queue.items(); System.out.println("队列里面真实的数组打印:"); queue.printRealArray(); } }

你可能感兴趣的:(数据结构和算法,数据结构,算法,学习)