java数据结构之环形队列(数组实现)

前言

算法是支撑整个程序运行的基础,所以要想成为一个大佬级别,算法知识就是必不可少的,接下来给大家分享一下自己最近学习的算法。

1.引出问题

环形队列只要来解决什么问题呢?
首先想到银行排队问题,大多数解决思路是生成一个有序集合用来存储需要进行排队的顾客(队列)。新增一个顾客,就将该顾客放入到集合(队列)中,并且长度+1;当取出一名顾客时,移除集合(队列)的头部分,集合(队列)的长度不变。

2.问题分析

这种解决思路固然能够解决问题,但是选用集合的方式是不合理的,原因如下:
(1)集合不能够复用。
(2)占用本地内存太大。

3.对上述问题进行代码演示

为了方便直接利用数组来存储队列(话不多说直接上代码)

3.1代码中方法的陈诉

(1)利用指针的方式来进行存取数据
front 在取数据时,自动向后+1
rear 在存数据时,自动向后+1
(2)在设定指针初始值时默认都是-1
front :表示指向该队列首元素的前一个位置
rear:表示指向该队列末元素的位置
(3)参考代码如下

package com.haiyi.queue;

import java.util.Scanner;

/**
 * 
 * -使用数组来模拟队列 -----代码需要优化:其中存在两个问题(1)存放队列的数组没有清空 (2)存放队列的数组不能够重复使用
 * -----优化方式:采用--环形队列的方式
 * 
 * @author Administrator
 * 
 */
public class ArrayQueueDemo {

	public static void main(String[] args) {
		// 进行测试
		ArrayQueue arrayQueue = new ArrayQueue(3);
		Scanner sc = 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),查看队列头的数据");
			char key = sc.next().charAt(0);

			switch (key) {
			case 's':
				try {
					arrayQueue.showQueue();
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'e':
				loop = false;
				break;
			case 'a':
				System.out.println("请输入要添加的队列数");
				int n = sc.nextInt();
				arrayQueue.addQueue(n);
				break;
			case 'g':
				try {
					int data = arrayQueue.getQueue();
					System.out.println("取出来的数据是" + data);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'h':
				try {
					System.out.println("队列的头数据是"+arrayQueue.headQueue());
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			default:
				break;
			}
		}
		sc.close();
	}
}

/**
 * 数组队列类
 */
class ArrayQueue {
	// 数组的最大容量
	private int maxSize;
	// 队列的头
	private int front;
	// 队列的尾
	private int rear;
	// 存放队列的数组
	private int[] arr;

	// 初始化方法
	public ArrayQueue(int arrMaxSize) {
		this.maxSize = arrMaxSize;
		front = -1; // 指向队列的头部,分析front是指向队列头的前一个位置
		rear = -1;// 指向队列的尾部,分析rear是指向队列的最后一个数据
		this.arr = new int[maxSize];
	}

	// 判断队列是否满
	public boolean isFull() {
		return rear == (maxSize - 1);
	}

	// 判断队列是否为空
	public boolean isEmpty() {
		return front == rear;
	}

	// 向队列添加数据
	public void addQueue(int n) {
		if (isFull()) {
			System.out.println("队列已满不能够加入数据");
			return;
		}
		rear++; // 始终指向队列的头
		arr[rear] = n; // 向数组中添加数据
		System.out.println("添加成功");
	}

	// 向队列中取数据
	public int getQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列为空,不能取数据");
		}
		front++;
		return arr[front];
	}

	// 展示队列中所有的数据
	public void showQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列为空");
		}
		for (int i = 0; i < arr.length; i++) {
			System.out.printf("arr[%d]=%d\n", i, arr[i]);
		}
	}

	// 展示队列的头部
	public int headQueue() {
		if (isEmpty()) {
			throw new RuntimeException("队列为空");
		}
		return arr[front + 1];
	}
}
3.2代码运行结果演示
3.2.1 初始队列为空

java叫号系统队列应用 java队列解决排队问题_数据

3.2.2 添加数据到队列并展示

java叫号系统队列应用 java队列解决排队问题_java叫号系统队列应用_02

3.2.3 从队列中取出数据

java叫号系统队列应用 java队列解决排队问题_数组_03

3.2.4 全部取出后队列为空

java叫号系统队列应用 java队列解决排队问题_数组_04

4.小结

(1)本次学习需要明白基本队列的如何使用
(2)本次学习需要明白出现环形队列的原因。
(3)第一次写博客有点小紧张,不足之处希望大家指出来,共同进步。纯手打,希望分享的这点经验能够帮助到大家。