数据结构之循环队列

该博客详细介绍了循环队列的结构及其初始化过程,包括如何判断队列是否满、是否空以及有效数据个数的计算。博客还展示了如何在循环队列中添加和获取数据,并提供了一个完整的测试代码来演示这些操作。循环队列是一种重要的数据结构,常用于解决数据缓冲和高效存取的问题。
摘要由CSDN通过智能技术生成

循环队列的结构:

            private Integer maxSize; // 队列的最大数量
            private Integer front; // 队列的头 
            private Integer rear; // 队列的尾
            private int[] arr; // 定义数组用于存放数据
  

循环队列的初始化: 

        若使其为循环队列,则队列的头指向队列的第一个也就是front = 0;

        队列的尾指向队列的第一个元素的下一个,初始化时没有元素,所以第一个元素的下一位也是0,即rear = 0;

 构造函数为: 

public ArrayQueue2(Integer maxSize) {
		this.maxSize = maxSize; // 给最大值赋值
		arr = new int[this.maxSize]; // 初始化数组
		front = 0;
		rear = 0; // 循环指针都为零
	}

 判断队列是否满的条件:

        当使用循环队列时我们要拿出一个空间作为连接点,当然这个连接点也是动态的,也就是以一个空间为代价换取其它空间的重复使用。

        判断是否满的表达式是:(队列尾指针 + 1) % 队列最大长度 == 队列头指针;

                                 也就是:(rear + 1) % maxSize == front;

        原因:maxSize是表示队列的长度,假如是4,那数组下标是按照0--3的也就是rear和front最大只能到3,之后又重新为0。前面也说过要拿出一个空间作为连接点,这个连接点是动态的,所以消耗一个空间,maxSize是4,则最大只能存放3个空间的数据;

public boolean isFull() {
		return (rear + 1) % maxSize == front; // 判断是否满了
	}

判断是否为空:

        当队列中未添加数据时为空,此时rear和front都处于0位置,即rear == front;

public boolean isEmpty() {
		return rear == front; // 判断是否为空(指针无移动)
	}

判断有效数据个数:

        表达式:(队列尾指针 + 队列长度 - 队列头指针) % 队列的长度;

                即:(rear + maxSize - front) % maxSize;

普通的队列有效数据个数:(rear - front)就可以了

但是这里是循环队列,rear到达maxSize - 1时,取出第一个数据,arr[0]空出来,rear的下一个位置将是0; 此时的0 - front就是一个负数,当我们加上maxSize的时候就可以放心的去减去front;

// 展示所有数据
	public void show() {
		if(isEmpty()) {
			System.out.println("队列为空,无法编列");
			return;
		}
		for(int i = 0; i < (rear + maxSize - front) % maxSize; i++) {
			System.out.println("arr["+ (front + i)  +"]=" + arr[front + i]);
		}
	}

存放数据:

        为了保证在rear到达maxSize - 1时候,下一次移动到0的位置,我们则需要

rear = (rear + 1) % maxSize;

// 添加数据
	public void addQueue(Integer data){
		if(isFull()) {
			System.out.println("队列已满,无法添加数据!");;
			return;
		}
		arr[rear] = data;
		rear = (rear + 1) % maxSize;
	}

拿出数据:

        此时同理:为了保证在front到达maxSize - 1时候,下一次移动到0的位置,我们则需要

front= (front+ 1) % maxSize;

        拿出头数据是为了方便我们观察队列的变化;

// 拿出数据
	public int getQueue(){
		if(isEmpty()) {
			throw new RuntimeException("数组为空,无法拿到数据!");
		}
		int value = arr[front];
		front = (front + 1) % maxSize;
		return value;
	}
	
	// 拿出头数据
	public int gethead(){
		if(isEmpty()) {
			throw new RuntimeException("数组为空,无法拿到数据!");
		}
		return arr[front];
	}
	

整个程序的测试代码:

import java.util.Scanner;

public class CirArrayQueue {
	public static void main(String[] args) {
		
		ArrayQueue2 arrayQueue = new ArrayQueue2(4);
		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': {
				arrayQueue.show();
				break;
			}
			case 'a': {
				int value = scanner.nextInt();
				arrayQueue.addQueue(value);
				break;
			}
			case 'g': {
				try {
					int queue = arrayQueue.getQueue();
					System.out.println("取出的数据是[" + queue + "]");
				} catch (Exception e) {
					// TODO Auto-generated catch block
					System.out.println(e.getMessage());
				}
				break;
			}
			case 'h': {
				try {
					int firstQueue = arrayQueue.gethead();
					System.out.println("取出的头数据是[" + firstQueue + "]");
				} catch (Exception e) {
					// TODO Auto-generated catch block
					System.out.println(e.getMessage());
				}
				break;
			}
			case 'e': {
				scanner.close();
				loop = false;
				break;
			}
			default:
				throw new IllegalArgumentException("Unexpected value: " + key);
			}
		}
		System.out.println("程序退出");
	}
	
	
}

class ArrayQueue2{
	
	private Integer maxSize; // 队列的最大数量
	private Integer front; // 队列的头 
	private Integer rear; // 队列的尾
	private int[] arr; // 定义数组用于存放数据
	
	
	public ArrayQueue2(Integer maxSize) {
		this.maxSize = maxSize; // 给最大值赋值
		arr = new int[this.maxSize]; // 初始化数组
		front = 0;
		rear = 0; // 循环指针都为零
	}
	
	public boolean isFull() {
		return (rear + 1)%maxSize == front; // 判断是否满了
	}
	
	public boolean isEmpty() {
		return rear == front; // 判断是否为空(指针无移动)
	}
	
	// 添加数据
	public void addQueue(Integer data){
		if(isFull()) {
			System.out.println("队列已满,无法添加数据!");;
			return;
		}
		arr[rear] = data;
		rear = (rear + 1) % maxSize;
	}
	
	// 拿出数据
	public int getQueue(){
		if(isEmpty()) {
			throw new RuntimeException("数组为空,无法拿到数据!");
		}
		int value = arr[front];
		front = (front + 1) % maxSize;
		return value;
	}
	
	// 拿出头数据
	public int gethead(){
		if(isEmpty()) {
			throw new RuntimeException("数组为空,无法拿到数据!");
		}
		return arr[front];
	}
	
	// 展示所有数据
	public void show() {
		if(isEmpty()) {
			System.out.println("队列为空,无法编列");
			return;
		}
		for(int i = 0; i < (rear + maxSize - front) % maxSize; i++) {
			System.out.println("arr["+ (front + i)  +"]=" + arr[front + i]);
		}
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值