顺序队列

一、队列
  • 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表;

  • 进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

  • 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出线性表;

  建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置,如图所示

在这里插入图片描述
  每次在队尾插入一个元素是,rear+1;每次在队头删除一个元素时,front+1;随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。当front=rear时,队列中没有任何元素,称为空队列;
在这里插入图片描述

二、实现一个顺序队列
  1. 数据结构
class Queue<E> {
    private int front;//队头
    private int rear;//队尾
    private Object[] elem;
    public Queue() {
        this(10);
    }
    public Queue(int size) {
        this.front = 0;
        this.rear = 0;
        this.elem = new Object[size];
    }
}
  1. 具体操作
  • 入队列:当队列未满时,在rear索引位置添加元素,rear自增;
    //入队列
    public void push(int val) {
        if (isFull()) {
            System.out.println("队列已满,元素无法入队");
            return;
        } else {
            this.elem[this.rear++] = val;
        }

    }
  • 出队列:在队列不为空时,出队列只需让front指针后移即可;
    //出队列
    public void pop() {
        if (isEmpty()) {
            throw new UnsupportedOperationException("队列为空,无法出队");
        }
        this.front++;
    }
  • 查看队首元素:队列不为空时,返回front索引位置的元素,不进行删除操作;
    //查看队首元素
    public E peek() {
        if (isEmpty()) {
            throw new UnsupportedOperationException("队列为空,无队首元素");
        }
        E data = (E)this.elem[this.front];
        return data;
    }
  • 判断队列是否为空

空队列的条件:当front与rear相等;

    //判空
    public boolean isEmpty() {
        return this.front == this.rear;
    }
  • 判满:当rear指针指向数组的最后一个位置时,再进行添加元素则会抛出空指针异常,可以看出,队列的可用空间其实是比原始数组的长度小一个单位的;
    //判满
    public boolean isFull() {
        return this.rear == this.elem.length-1;
    }
  • 打印队列元素
    //打印
    public void show() {
        if (this.front == this.rear) {
            System.out.println("空队列");
            return;
        }
        for (int i = this.front;i < this.rear;i++) {
            System.out.print(this.elem[i] + " ");
        }
        System.out.println();
    }
三、顺序队列的溢出问题

  当rear增加到指向分配的连续空间之外时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用,这些空间是已经出队的队列元素曾经占用过得存储单元,如图;
在这里插入图片描述
  进行了一定数量入队和出队操作后,可能会出现这样的情况:尾指针rear已指到数组的最后一个元素.即rear==MaxSize-1.此时若再执行入队操作,便会出现队满“溢出”。然而,由于在此之前可能也执行了若干次出队操作.因而数组的前面部分可能还有很多闲置的元素空间,即这种溢出并非是真的没有可用的存储空间,故称这种溢出现象为“假溢出”。

  • 真溢出:在顺序队列中,由于数组空间不够而产生的溢出称为真溢出;

  • 假溢出:顺序队列因多次入队列和出队列操作后出现的有内存空间但不能进行入队列操作的溢出称为假溢出

四、如何解决顺序队列的溢出问题?
  • 当队列真溢出时,可以采用给数组扩容的方式来增加存储空间,也可以每一次入队出队操作时,用Arrays.copyOf()方法使队列的长度等于存储元素的个数,不过这样是比较浪费的,且扩容之后,队列不会出现假溢出的情况;
  • 假溢出带来的存储空间闲置的问题,使顺序队列没有太多使用价值。为了解决这个问题,引入了循环队列的概念,请点击循环队列
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值