java数据结构与算法学习(三)

java数据结构与算法学习(三)

1.数组模拟循环队列

由上篇可知,如果我们直接用数组来模拟队列,那么在取出头部元素的时候,其头部元素仍然还是占着队列的内存的,无法再一次新添新元素进入该队列。

因此,我们这次来用数组来模拟一个循环的队列。
在这里插入图片描述
由图可知,循环队列的内存是可以灵活变动的。

注意
maxSize: 队列的最大容量
front: 循环队列的头部,此时的front直接指向的是 该队列的第一个元素
rear: 队列的尾部, 此时的rear直接指向的是 该队列最后一个元素的下一位

判断队列为空的条件: front == rear ; 判断队列为满的条件(rear + 1)% maxSize == front ; //如果rear的下一位就是front的话,那么就说明该队列满了

元素入队的关键
arr[rear] = n ;
rear = (rear + 1) % maxSize ;

元素出队的关键
int value = arr[front] ; //先保存即将出队的元素,即队头元素
front = (front + 1) % maxSize ; //将front往后移动一位
return value ; //返回队头元素,此时循环队列已经没有了该元素的内存占用了

该循环队列的有效数值总数
(rear + maxSize - front) % maxSize ; //因为是循环队列,因此其有效值的长度是尾部rear - 头部front + 最大值maxSize 然后取模maxSize的结果
}

package queue;

public class circleArrayQueue {
	private int maxSize; //队列的最大容量
	private int front; //头部,因为循环队列的front指的是队列的第一个元素,因此直接是front = 0
	private int rear; //尾部,循环队列的rear指的是队列的最后一个元素的下一位
	private int[] arr;
	
	//构造器
	public circleArrayQueue(int arrMaxSize) {
		maxSize = arrMaxSize;
		arr = new int[maxSize];
		//front = 0; //此处无需定义front和rear的值
		//rear = 0; 
	}
	
	//判断队列是否为空
	public boolean isEmpty() {
		return rear == front;
	}
	
	//判断队列是否为满
	public boolean isFull() {
		return (rear + 1) % maxSize == front; //因为是循环队列,所以当rear的下一位的值等于front的话,将说明此队列已经满了
	}
	
	//入队
	public void addQueue(int n) {
		//判断是否为满
		if (isFull()) {
			System.out.println("此队列已满,无法入队!");
		}
		arr[rear] = n;
		rear = (rear + 1) % maxSize;
	}
	
	//出队
	public int outQueue() {
		//判断是否队空
		if (isEmpty()) {
			throw new RuntimeException("此队列为空,无法出队!");
		}
		int value = arr[front]; //暂时保存队列的第一位元素
		front = (front + 1) % maxSize; //front往后移动一位
		return value; //成功返回队列的第一位元素
	}
	
	//获取队列的全部元素
	public void showQueue() {
		//判断是否队空
		if (isEmpty()) {
			System.out.println("此队列为空!");
		}
		//因为是循环队列,因此i直接等于front,然后遍历的范围是在front基础上的循环队列的有效长度,即front + size()
		for (int i = front; i < front + size(); i++) {
			System.out.printf("arr[%d] = %d\n",i % maxSize , arr[i % maxSize] );
		}
	}
	
	//获取循环队列的有效值的总数
	public int size() {
		return (rear + maxSize - front) % maxSize; //因为是循环队列,因此其有效值的长度是尾部rear - 头部front + 最大值maxSize 然后取模maxSize的结果
	}
	
	//获取队列的头部元素
	public int getHeadQueue() {
		//判断队列是否为空
		if(isEmpty()) {
			throw new RuntimeException("此队列为空!");
		}
		return arr[front]; //由于循环队列的front直接指的是队列的第一位元素,因此直接输出即可
	}
}

测试文件

package queue;
import java.util.Scanner;

import queue.*;

public class testCircleArrayQueue {

	public static void main(String[] args) {
		// 测试模拟队列的数组
		
		//创建一个最大容量是4的队列
		circleArrayQueue queue = new circleArrayQueue(4);
		Scanner scanner = new Scanner(System.in);
		char key = ' '; //用于接收用户的输入值
		boolean loop = true; //用于while循环的状态表示
		
		System.out.println("+++数组模拟循环队列的测试+++");
		while(loop) {
			//制作选项菜单
			System.out.println("\n\n++++++++++++++++++++++++++++++++++++");
			System.out.println("s(show) 显示该队列全部内容");
			System.out.println("a(add) 添加元素进入队列");
			System.out.println("o(out) 将队列头部元素出队");
			System.out.println("g(get) 获取队列头元素");
			System.out.println("e(exit) 退出");
			System.out.println("++++++++++++++++++++++++++++++++++++");
			
			System.out.println("请做出你的选择:");
			key = scanner.next().charAt(0); //charAt(0)方法表示仅仅接收1个字符,防止用户输入的是数量>1的值
			
			switch(key) {
				case 's':
					queue.showQueue();
					break;
				case 'a':
					try {
						System.out.println("请输入你要添加的元素:");
					int n = scanner.nextInt();
					queue.addQueue(n);
					}catch(Exception e) {
						System.out.println(e.getMessage());
					}
					
					break;
				case 'o':
					try {
						int res = queue.outQueue();
						System.out.printf("取出的元素是%d\t", res);
					}catch(Exception e){
						System.out.println(e.getMessage());
					}
					break;
				case 'g':
					try {
						int res = queue.getHeadQueue();
						System.out.printf("获取的队列头元素是%d\t", res);
					}catch(Exception e) {
						System.out.println(e.getMessage());
					}
					break;
				case 'e':
					loop = false;
					break;
				default:
					break;
			}
		}
		scanner.close(); //将scanner关闭
		System.out.println("已退出!");
	}

}

测试之后的结果:

- - 当队列未添加任何元素时,直接查看队列
在这里插入图片描述
- - 当队列先后添加11、22两个元素之后
在这里插入图片描述
- - 尝试取出头部元素时,已经成功取出了11
在这里插入图片描述
- - 再查看一下该队列的头部元素,它已经是22了
在这里插入图片描述
- - 然后查看整一个队列,发现此时只有arr[1]的22了,所以当arr[0]的11出队之后,其并未继续占用该队列的内存
在这里插入图片描述
- - 往循环队列插入新值33,再查看整一个队列的时候,发现arr[1]和arr[2]的值分别是22,33
在这里插入图片描述
- - 运行成功!

————————————————————————————————————————————
上一篇
java数据结构与算法学习(二)
java数据结构与算法学习(四)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值