当前位置: 首页 > news >正文

2.环形队列

文章目录


1.队列介绍

  • 队列是一个有序列表,可以用数组(顺序存储)或是链表(链式存储)来实现
  • 遵循先入先出的原则,即:先存入队列的数据,要先取出,后存入的要后取出
  • 在这里插入图片描述
  • 在这里插入图片描述

在这里插入图片描述

--存在问题,一次性使用,解决方法:变为环形队列
-原数据:-------------------------------------------------------------------------------------
package Queue2;

import java.util.Iterator;
import java.util.Scanner;



public class ArrayQueueDemo {

	public static void main(String[] args) {
		//测试
		//创建一个队列
		ArrayQueue queue = new ArrayQueue(3);
		char key = ' ';//接收用户输入
		Scanner scanner=new Scanner(System.in);//扫描器
		boolean loop = true;//控制循环,默认死循环
		//输出一个菜单
		while(loop) {
			System.out.println("s(show):显示队列");
			System.out.println("e(exit):退出队列");
			System.out.println("a(add):添加数据到队列");
			System.out.println("g(get):从队列取出数据");
			System.out.println("h(head):查看队列头的数据");
			key = scanner.next().charAt(0);//接收一个字符
			switch (key) {
			case 's': {
				queue.showQueue();
				break;
			}
			case 'a': {
				System.out.println("输出一个数:");
				int value = scanner.nextInt();
				queue.addQueue(value);
				break;
			}
			case 'g': {//取出数据
				try {
					int res = queue.getQueue();
					System.out.printf("取出的数据是:%d\n",res);
					
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			}
			case 'h': {//查看队列头的数据
				try {
					int res = queue.headQueue();
					System.out.printf("队列头的数据是:%d\n",res);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			}
			case 'e': {//退出
				scanner.close();//关闭
				loop=false;
				break;
			}
			default:
				break;
			}
		}
		System.out.println("程序退出");
	}

}
//使用数组模拟队列-编写一个ArrayQueue类
class ArrayQueue{
	private int maxSize ;//表示数组的最大容量
	private int front;//队列头
	private int rear;//队列尾
	private int[] arr;//该数据用于存放数据,模拟队列
	
	//创建队列的构造器
	public ArrayQueue(int arrMaxSize) {
		maxSize = arrMaxSize;
		arr = new int[maxSize];//初始化
		front = -1;//指向队列头部,分析出front是指向队列头的前一个位置
		rear = -1;//指向队列尾,指向队列尾的具体数据(即队列的最后一个数据)
			
	}
	//判断队列是否满
	public boolean isFull() {
		return rear == maxSize-1;
	}
	
	//判断队列是否为空 //rear=front
	public boolean isEmpty() {
		return rear ==front;
	}
	
	//添加数据到队列
	public void addQueue(int n) {
		//先判断队列是否满
		if(isFull()) {
			System.out.println("不能加入数据");
			return;
		}
		rear++;//让rear后移
		arr[rear] = n;
		
	}
	
	//获取队列的数据,出队列,从front开始获取\
	public int getQueue() {
		//判断队列是否为空
		if(isEmpty()) {
			//通过抛出异常
			throw new RuntimeException("队列空");
		}
		//不为空,取数据
		front ++;//front后移
		return arr[front];
		
	}
	//显示队列的所有数据
	public void showQueue() {
		//遍历
		//为空
		if(isEmpty()) {
			System.out.println("队列空,没有数据...");
			return;
		}
		//不为空
		for(int i = 0 ; i < arr.length ;i++) {
			System.out.printf("arr[%d] = %d\n",i,arr[i]);//[%d]下标
		}
	}
	//显示队列的头数据,注意不是取出数据
	public int headQueue() {
		//判断
		if(isEmpty()) {
			throw new RuntimeException("队列空,没有数据...");
		}
		return arr[front+1];
	}
}

在这里插入图片描述

  • 思路:(通过取模方式实现)
    • front变量的含义做一个调整,front指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素,front初始值=0
    • rear变量的含义做一个调整:rear指向最后一个元素的后一个位置,用来空出一个空间(动态变化)作为约定,rear初始值=0
    • 当队列满时,条件改为(rear+1)%maxSize == front
    • 当队列为空的条件,rear = front
    • 队列中有效数据的个数变为 (rear + maxSize-front) %maxSize. 例如:rear=1 ,front=0
package Queue2;

import java.util.Scanner;

public class CircleArrayQueue {

	public static void main(String[] args) {
		System.out.println("环形队列测试");
		//测试
		//创建一个队列
		CircleArray queue = new CircleArray(4);//说明设置4,其队列的有效数据最大是3
		char key = ' ';//接收用户输入
		Scanner scanner=new Scanner(System.in);//扫描器
		boolean loop = true;//控制循环,默认死循环
		//输出一个菜单
		while(loop) {
			System.out.println("s(show):显示队列");
			System.out.println("e(exit):退出队列");
			System.out.println("a(add):添加数据到队列");
			System.out.println("g(get):从队列取出数据");
			System.out.println("h(head):查看队列头的数据");
			key = scanner.next().charAt(0);//接收一个字符
			switch (key) {
			case 's': {
				queue.showQueue();
				break;
			}
			case 'a': {
				System.out.println("输出一个数:");
				int value = scanner.nextInt();
				queue.addQueue(value);
				break;
			}
			case 'g': {//取出数据
				try {
					int res = queue.getQueue();
					System.out.printf("取出的数据是:%d\n",res);
					
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			}
			case 'h': {//查看队列头的数据
				try {
					int res = queue.headQueue();
					System.out.printf("队列头的数据是:%d\n",res);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			}
			case 'e': {//退出
				scanner.close();//关闭
				loop=false;
				break;
			}
			default:
				break;
			}
		}
		System.out.println("程序退出");
	}

	}


class CircleArray{
	private int maxSize ;//表示数组的最大容量
	//front变量的含义做一个调整,front指向队列的第一个元素,
	//也就是说arr[front]就是队列的第一个元素,front初始值=0
	private int front;//队列头
	//rear变量的含义做一个调整:rear指向最后一个元素的后一个位置
	//,用来空出一个空间(动态变化)作为约定,rear初始值=0
	private int rear;//队列尾
	private int[] arr;//该数据用于存放数据,模拟队列
	
	public CircleArray(int arrMaxSize) {
		maxSize = arrMaxSize;
		arr = new int[maxSize];
	}
	//判断队列是否满
		public boolean isFull() {
			return (rear+1)%maxSize == front;
		}
		
		//判断队列是否为空 //rear=front
		public boolean isEmpty() {
			return rear ==front;
		}
		
		//添加数据到队列
		public void addQueue(int n) {
			//先判断队列是否满
			if(isFull()) {
				System.out.println("不能加入数据");
				return;
			}
			指向最后一个元素的后一个位置
			//直接将数据加入
			arr[rear] = n;
			//将rear后移,必须考虑取模,向前面移动
			rear = (rear +1)%maxSize;
		}
		//获取队列的数据,出队列,从front开始获取\
		public int getQueue() {
			//判断队列是否为空
			if(isEmpty()) {
				//通过抛出异常
				throw new RuntimeException("队列空");
			}
			//这里需要分析front是指向队列的第一个元素
			//1.想把front对应的值保留到一个临时变量
			//2.将front后移,考虑取模
			//3.将临时保存的变量返回
			int value = arr[front];
			front = (front+1)%maxSize;
			return value;
		}
	
		//显示队列的所有数据
		public void showQueue() {
			//遍历
			//为空
			if(isEmpty()) {
				System.out.println("队列空,没有数据...");
				return;
			}
			//思路:从front开始遍历,遍历多少个元素
			//理解清楚
			for(int i = front ; i < front+size() ;i++) {
				System.out.printf("arr[%d] = %d\n",i%maxSize,arr[i%maxSize]);//[%d]下标
			}
		}
		//求出当前队列的有效个数
		public int size() {
			//rear = 2 front = 1 maxSize=3
			return (rear + maxSize-front) %maxSize;
		}
		//显示队列的头数据,注意不是取出数据
		public int headQueue() {
			//判断
			if(isEmpty()) {
				throw new RuntimeException("队列空,没有数据...");
			}
			return arr[front];
		}
}

相关文章:

  • LangChain vs LlamaIndex:构建 AI 知识库系统(文本嵌入、向量数据库)
  • C语言:几种字符串常用的API
  • 13.我的seafile网盘,多端同步我做主
  • Redis(笔记)
  • TypeScript面试题集合【初级、中级、高级】
  • DiffAD:自动驾驶的统一扩散建模方法
  • ChatGPT 4:解锁AI文案、绘画与视频创作新纪元
  • 蓝桥杯 web 水果拼盘 (css3)
  • Elasticsearch DSL 中的 aggs 聚合
  • 字符串的replace、replaceAll、split()方法
  • 主流程发起,去除子流程的时长计算问题
  • 【愚公系列】《高效使用DeepSeek》055-可靠性评估与提升
  • sklearn的Pipeline
  • Kotlin 中的 `reified` 关键字全解析:保留类型信息 + 优化高阶函数的双重魔法
  • 中国钧瓷收藏市场现状和风险警示
  • 1.1 测试计划阶段:如何制定高效的测试策略
  • JS页面尺寸事件
  • 软件项目管理
  • MySQL-SQL-DML语句、INSER添加数据、UPDATE更新数据、DELETE删除数据
  • 阅读笔记“Wi-BFI”
  • wordpress网站公告/北京seo学校
  • 湛江模板建站多少钱/株洲seo优化报价
  • 网站开发什么是会话/全网营销方案
  • 柳林网站建设/品牌推广战略
  • 建设一个广告联盟的网站/全球搜官网
  • 日挣100元的微信小兼职/seo在线教学