【数据结构】java实现队列

本文介绍了队列的基本概念,包括其作为先进先出数据结构的特性,以及队列的抽象数据类型描述。接着详细阐述了队列的顺序存储实现,包括非循环队列和循环队列的代码实现,探讨了如何判断队列的满与空状态。

目录

01 队列概述

02 队列的抽象数据类型描述

03 队列顺序存储实现(非循环队列)

04 循环队列的代码实现

01 队列概述

  • 队列(Queue):具有一定操作约束的线性表
    • 插入和删除操作:只能在一端插入,而在另一端删除
    • 数据插入: 入队列(addQueue)
    • 数据删除:出队列(deleteQueue)
    • 先来先服务
    • 先进先出

02 队列的抽象数据类型描述

类型名称:队列(Queue)

数据对象集:一个有0个或多个元素的有穷线性表。
操作集:长度为MaxSize的队列Q  Queue,队列元素item  ElementType
1、Queue CreatQueue( int MaxSize ):生成长度为MaxSize的空队列;
2、Boolean IsFullQ( Queue Q, int MaxSize ):判断队列Q是否已满;
3、void AddQ( Queue Q, ElementType item ): 将数据元素item插入队列Q中;
4、Boolean IsEmptyQ( Queue Q ): 判断队列Q是否为空;
5、ElementType DeleteQ( Queue Q ):将队头数据元素从队列中删除并返回。

03 队列顺序存储实现(非循环队列)

队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。

front指向第一个元素的前一个位置,这里代码没有考虑到队列空间的重复利用 

// 使用数组模拟队列
class ArrayQueue{
    private int[] arr; //数组模拟队列
    private int maxSize;  // 最大容量
    private int front; // 头指针,用于添加数据
    private int rear; // 尾指针,用于删除数据

    public ArrayQueue(int maxSize) {  //队列初始化
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front = -1; // 指向队列头部的前一个位置
        rear = -1; // 指向队列尾部
    }

    public boolean isFull(){
        return rear == maxSize - 1;
    }

    public boolean isEmpty(){
        return front == rear;  // 队列为空时front不一定是-1
    }

    // 添加数据到队列
    public void addQueue(int num){
        if(isFull()){
            System.out.println("队列满");
            return;
        }
        rear++; // 还可以添加时,尾指针后移
        arr[rear]  = num;
    }

    // 从队列删除数据,出队列
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        int num ; // 存放取出的数据
        front++;
        num = arr[front];
        return num;
    }

    // 显示队列所有数据
    public void showQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        for(int i = front + 1 ; i <= rear; i++){
            System.out.println(arr[i]);
        }
    }

    // 取出头数据
    public int peek(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return arr[front + 1];
    }
}

04 循环队列的代码实现

front 和 rear指针的移动采用“加1取余”法实现顺序存储的“循环使用”

front 指向数据的第一个元素,初始化为0

rear指向队列的最后一个元素的后一个位置,同样初始化为0。

空出一个空间作为约定,仅使用n-1个空间

判断队列为空: rear == front

判断队列满: (rear + 1) % maxSize == front  , 队列满时,front指向第一个数,rear指向预留空间

 队列中有效数据个数: (rear + maxSize - front)% maxSize

// 使用数组模拟队列
class CircleQueue{
    private int[] arr; //数组模拟队列
    private int maxSize;  // 最大容量
    private int front; // 头指针,用于添加数据
    private int rear; // 尾指针,用于删除数据

    public CircleQueue(int maxSize) {  //队列初始化
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front = 0; // 指向队列头部
        rear = 0; // 指向队列尾部的后一个位置或环形队列的预留空间
    }

    public boolean isFull(){
        return (rear + 1) % maxSize == front;
    }

    public boolean isEmpty(){
        return front == rear;  // 队列为空时front不一定是-1
    }

    // 添加数据到队列
    public void addQueue(int num){
        if(isFull()){
            System.out.println("队列满");
            return;
        }
        arr[rear]  = num; // 已经指向后一个元素,所以直接加即可
        rear = (rear + 1) % maxSize; // 还可以添加时,尾指针后移
    }

    // 从队列删除数据,出队列
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        // front指向队列的第一个元素
        int num = arr[front]; ; // 存放取出的数据
        front = (front + 1) % maxSize;
        return num;
    }

    // 显示队列所有数据
    public void showQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        // 从front开始遍历,判断有多少个元素
        for(int i = front ; i <= rear + getSize(); i++){
            System.out.println(arr[i % maxSize]); // 不然会下标越界
        }
    }

    // 判断当前队列有效数据的个数
    public int getSize(){
        return (rear + maxSize - front) % maxSize;
    }

    // 取出头数据
    public int peek(){
        if(isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值