Java环形数组实现队列

1.介绍

队列就是:只能头删尾增,就跟我们去网红小店排队一样

 主要使用环形数组实现是因为环形数组具有以下的优点:

1.移除头部元素后序的元素都不需要向前移动,只需要头指针移动即可

2.任意一个节点都可以当做头部尾部(一般数组都是0索引当做头部)

3.因为通过取模运算,形成了环形,不会出现数组越界的情况

4.数组自身就具有良好的性能,比如:局部性原理和cpu缓存

2.思路分析

2.1判空

头尾指针指向同一位置即为空

2.2判满

正常思维的话:我们判满的条件不也是同一位置吗,但是如果这样就和判空冲突了

所以我们就需要通过来浪费空间来换取时间的效率了(牺牲一个数组元素来判满)

当 ( 尾 + 1)% 数组长度 = 头  就表示满了 (之所以%A数组长度就是因为:尾可能在数组最后在 + 1不会和0相等的)

2.3对判空判满进行小结

可以对上述优化:

        优化从start和end存的就是索引转换为逐渐递增的整数,这句话很抽象就跟B树与B+树的区别差不多

        就是尾指针你只要不添加元素,我就不管你是不是越界,然后我判空的条件就是 尾 - 头 = 数组长度

        这样其实也没有什么好优化的主要是可以少几次求摸运算 

2.4 尾增和头删

添加后尾指针移动一次, 删除后头指针移动一次

3.代码实现

3.1初始构建
public class ArraysQueue implements Iterable{

private T[] array;//数组
private int start;//头指针
private int end;//尾指针


public ArraysQueue(int initialCapacity){
    array = (T[]) new Object[initialCapacity + 1];//因为判满要牺牲一个所以要多创建一个
    start = 0;
    end = 0;
}
}
3.2判空
//判断是否为空
    public boolean isEmpty(){
        //如果头尾指针指向同一个位置既为空
        return start == end;
    }
3.3判满
//判满
    public boolean isFull(){
   
        return (end + 1) % array.length == start;
    }
3.4尾增
//入队
    public void offer(T element) {
        if (isFull()) {//判满
            System.out.println("队列已满,无法入队");
            return;
        }
        array[end] = element;//在尾部添加  (注意不许合并end++) 会越界的
        end = (end + 1) % array.length;//尾巴向后移动一下
    }
3.5头删
//删除并获取被删除的元素
    public T poll() {
        if (isEmpty()) {//判空
            System.out.println("队列为空,无法出队");
            return null; // 或者抛出异常
        }
        T element = array[start];
        start = (start + 1) % array.length;
        return element;
    }
3.6迭代器遍历
//实现迭代器遍历
    public Iterator iterator(){
        return new Iterator() {
            int p = start;
            @Override
            public boolean hasNext() {
                return p != start;//不循环的条件
            }

            @Override
            public T next() {
                T value = array[p];
                p = (p + 1) % array.length;//后移
                return value;
            }
        };
    }

总结一下:

对于上述代码,你可以想想怎么优化?

        1.数组长度固定(可以使用自动扩容) 

        2.size记录长度不需要浪费空间

          

你可能感兴趣的:(java,开发语言,数据结构)