Java数据结构和算法之环形队列

实现原理:
创建的是顺序队列,通过取模操作,来实现环形队列。1.初始化rear为
代码实现:

package com.guigu.queue;

import java.util.Scanner;

/**
 * @author AZ
 * @describe 用数组实现的环形队列
 */

public class QueueDemo02 {
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入队列的长度:");
		int maxSize = scanner.nextInt();
		ArrayQueue arrQueue = new ArrayQueue(maxSize);
		boolean isFlag = true; //用来控制程序退出
		char key = ' '; //用来接收命令
		while(isFlag) {
			System.out.println("a(添加数据)");
			System.out.println("s(展示队列数据)");
			System.out.println("e(退出程序)");
			System.out.println("h(获得队首数据)");
			System.out.println("g(取出数据)");
			System.out.println("请选择你要执行的操作:");
			key = scanner.next().charAt(0);
			switch(key) {
				case 'a':
					System.out.println("请输入一个整数:");
					int value = scanner.nextInt();
					arrQueue.addQueue(value);
					break;
				case 's':
					arrQueue.showQueue();
					break;
				case 'e':
					isFlag = false;
					break;
				case 'h':
					try {
						int headValue = arrQueue.getHeadValue();
						System.out.println("队首元素为:" + headValue);
						break;
					} catch (Exception e) {
						System.out.println(e);
					}
				case 'g':
					try {
						int getValue = arrQueue.getQueue();
						System.out.println("取出元素:" + getValue);
						break;
					} catch (Exception e) {
						System.out.println(e);
					}
			}
		}
		System.out.println("程序结束!!");
	}
	
}


//定义一个队列的实现类,
class ArrayQueue{
	
	private int rear = 0; //队尾指针,初始化为0
 	private int front = 0; //队首指针,初始化为0
 	private int maxSize; //表示队列的容量
	private int[] queueData; //定义一个数组,用来存放队列的数据
 	
	//构造器,初始化一个队列
	public ArrayQueue(int queueSize) {
		this.maxSize = queueSize;
		this.queueData = new int[maxSize];
	}

	//插入元素,进队
	public void addQueue(int value) {
		//判断队列是否为满
		if(isFull()) {
			System.out.println("队列已满~~");
			return;
		}
		queueData[rear] = value; //rear当前所指位置就是待插入位置
		rear = (rear + 1) % maxSize; //rear往后移一位
	}
	
	//取出数据,出队
	public int getQueue() {
		//判断队列是否为空
		if(isEmpty()) {
			throw new RuntimeException("队列为空~~"); //因为方法有返回值,所以抛个异常
		}
		int value = queueData[front];
		front = (front + 1) % maxSize;
		return value;
	}
	
	//遍历队列
	public void showQueue() {
		//判断队列是否为空
		if(isEmpty()) {
			System.out.println("队列为空~~");
			return;
		}
		//有几个有效值就循环几次
		for(int i = front;i < front + getSize();i++) {
			System.out.printf("Queue[%d]=%d \n", i, queueData[i]);
		}
	}
	
	//获取队首元素
	public int getHeadValue() {
		if(isEmpty()) {
			throw new RuntimeException("队列为空~~");
		}
		return queueData[front];
	}
	
	//判断队列中的有效元素个数
	public int getSize() {
		return (rear + maxSize - front) % maxSize; 
	}
	
	//判断队列是否为空
	public boolean isEmpty() {
		return rear == front; //当队首指针和队尾指针相等时,说明队列为空 
	}
	
	/**
	 * 可能有人会好奇,为什么rear == front时是队列为空,而不是队列为满?
	 * 其实呢,当rear与front相等时, 这两种意思都可以表示
	 * 所以在rear与front相等时避免有歧义,在此呢我选择浪费一个内存空间来消除歧义
	 * 就是当rear和front相等时,就认为是队列为空,当rear+1和front相等时认为队列为满
	 * 此时始终让rear始终指向队尾元素的后一个位置,也就是待插入元素的位置	
	*/
	
	//判断队列是否已满
	public boolean isFull() {
		return (rear + 1 + maxSize) % maxSize == front; //此时说明队列已满
	}
}


总结: 思路并不太难,主要是理解rear和front相等时歧义的消除。如果对为什么每次移动rear和front都 取模以及判断有效值个数的时候的取模等操作不太理解,就画图看下,你就懂了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值