数据结构与算法(二)

什么是队列?

队列是一种特殊的线性表(线性结构),特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。-------------摘自百度百科

队列按照逻辑数据结构可以分为顺序队列和循环队列.

顺序队列存在假溢出的现象,如下图所示.
在这里插入图片描述
队列中的元素只能从尾部入队,从头部出队.如果这时 a1,a2 出队,front 后移动到 2,如图:
在这里插入图片描述
但是现在队列明明有三个空位,却只能向队列中存一个元素,这就是假溢出,针对这种情况,提出了循环队列的概念,就是后面满了,就再从头开始,也就是头尾相接的循环。

队列的实现方式

数组和链表

数组模拟队列的实现方式

(1) 我们用两个变量front和rear分别记录队列前后端的下标,front随着数据输出而改变,rear随着数据输入而改变,
front和rear的定义如下:
如下图所示:在这里插入图片描述
(2) 数据入队(addQueue)
1) 将尾针往后移动: rear + 1 ,当front == rear 就说明这是个空队列了.
2) 若尾针 rear < maxSize -1 ,则新来的元素可以存入rear所在的位置处, rear = maxSize -1 说明队列满了.
3) front的初始索引为-1,指向队列的头部,是头部元素的前一个位置,rear的初始索引为-1,指向队列的尾部元素,

数组模拟循环队列的实现方式

这是对数组模拟队列的优化,我们在这里把数组看作是一个环形(通过front和rear取模来实现),我们需要注意以下几点:
1). front 变量的含义: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素 ,front 的初始值 = 0
2). rear 变量的含义:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.rear 的初始值 = 0
3). 当队列满时,条件是 (rear + 1) % maxSize == front【满】
4). 对队列为空的条件, rear == front 空
5). 当我们这样分析, 队列中有效的数据的个数 (rear + maxSize - front) % maxSize //eg: rear = 1 front = 0 ,则只有一个元素在数组中.
6). 我们就可以在原来的队列上修改得到,一个环形队列
代码实现如下:

//数组实现循环队列,我们需要知道的常见方法定义(功能)有:判断队列是否为满,判断队列是否为空,添加数据到队列,出队,显示所有数据,显示队列有效数据个数,显示队列的头数据
/**
 * @description:数组实现的循环队列
 * @author: Tian
 * @time: 2020/7/21 8:06
 */

class CircleArray {

    private int maxSize;
    private int[] arr; // 该数组存放数据,模拟队列
    private int front; // 指向队列头部
    private int rear; // 指向队列的尾部

    public CircleArray(int arrMaxSize) {
        maxSize = arrMaxSize;
        arr = new int[maxSize];
    }

    public boolean isFull() {
        //尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定(!!!)
        return (rear + 1) % maxSize == front;
    }

    public boolean isEmpty() {
        return rear == front;
    }

    public void addQueue(int n) {
        if (isFull()) {
            System.out.println("队列满,无法加入..");
            return;
        }
        arr[rear] = n;
        rear = (rear + 1) % maxSize;
    }

    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列空~");
        }
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }
	
	 //当前队列的有效数据个数
    public int size(){
        return (rear+maxSize-front)%maxSize;
    }

    //遍历
    public void showQueue(){
        if (isEmpty()) {
            System.out.println("队列为空,没有数据");
            return;
        }
        int s =size();
        for(int i = front ; i < front +s;i++){
            System.out.println(arr[i%maxSize]);
        }
      
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值