categories:
- 数据结构与算法
tags: - 队列
title: 数据结构与算法之队列
date:
数据结构之队列
- 定义:有序列表,可以通过数组或者链表实现,遵循先入先出的原则
数组实现普通队列
-
示意图(从图中可以看出,通过队尾(指向最后一个元素)队首(指向第一个元素的前一位置)两个指针维护队列长度,加入队列时,front不变,rear++;出队列时rear不变,front++)
2.实现思想:
-
入队列时
-
尾指针rear向后移即rear+1,front==rear时(队列为空)
-
若尾指针小于最大下标maxsize-1,则将数据存入,若等于则报队列满,否则无法存入
-
代码实现
public void addQueue(int x) { if (isFull()) { System.out.println("队列已满,无法加入"); return; } //rear++; arr[++rear] = x; }
-
-
出队列时
-
头部指针front+1,
-
若rear==front,队列为空,报错
-
代码实现
public int getQueue() { if (isEmpty()) { throw new RuntimeException("队列空,无法获取"); } return arr[++front]; }
-
普通队列完整代码实现
package com.atguigu;
import java.util.Scanner;
public class arrayToQueue {
public static void main(String[] args) {
arrayQueue arrayQueue = new arrayQueue(3);
char key = ' ';
Scanner in = new Scanner(System.in);
boolean tag = true;
while (tag) {
System.out.println("s:显示队列\n");
System.out.println("e:退出程序\n");
System.out.println("a:添加数据\n");
System.out.println("g:取出数据\n");
System.out.println("h:查看头部数据\n");
key = in.next().charAt(0);
switch (key) {
case 's':
arrayQueue.showQueue();
break;
case 'a':
System.out.println("输入数字:");
int value = in.nextInt();
arrayQueue.addQueue(value);
break;
case 'g':
try {
int res = arrayQueue.getQueue();
System.out.println("取出的数据是" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int res = arrayQueue.headQueue();
System.out.println("队列头数据是" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'e':
in.close();
tag=false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class arrayQueue {
private int maxSize;
private int front;
private int rear;
private int[] arr;
public arrayQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
front = -1;
rear = -1;
}
public boolean isFull() {
return rear == maxSize - 1;
}
public boolean isEmpty() {
return rear == front;
}
//入队列
public void addQueue(int x) {
if (isFull()) {
System.out.println("队列已满,无法加入");
return;
}
//rear++;
arr[++rear] = x;
}
//出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空,无法获取");
}
return arr[++front];
}
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空,没有数据");
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
}
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法返回");
}
return arr[front + 1];
}
}
- 数组无法复用->将数组使用算法改进成环形数组达到空间利用的效果
数组模拟环形队列
1.思路
- 调整front为指向队列的第一个元素,rear指向队列的最后一个元素的后一个位置,是为了空出一个空间作约定(否则无法判断是满是空)
- 队列满的条件:(rear+1)%maxSize=front
- 队列空的条件:rear==front
- 队列中的有效数据个数:(rear+maxSize-front)%maxSize(rear比front小时代表已经跑了一圈)
2.实现
package com.atguigu;
import java.util.Scanner;
public class circleQueue {
public static void main(String[] args) {
circleArrayQueue arrayQueue = new circleArrayQueue(4);
char key = ' ';
Scanner in = new Scanner(System.in);
boolean tag = true;
while (tag) {
System.out.println("s:显示队列\n");
System.out.println("e:退出程序\n");
System.out.println("a:添加数据\n");
System.out.println("g:取出数据\n");
System.out.println("h:查看头部数据\n");
key = in.next().charAt(0);
switch (key) {
case 's':
arrayQueue.showQueue();
break;
case 'a':
System.out.println("输入数字:");
int value = in.nextInt();
arrayQueue.addQueue(value);
break;
case 'g':
try {
int res = arrayQueue.getQueue();
System.out.println("取出的数据是" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int res = arrayQueue.headQueue();
System.out.println("队列头数据是" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'e':
in.close();
tag = false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class circleArrayQueue {
private int maxSize;//数组的最大容量
private int front;//指向队列第一个元素
private int rear;//指向队列最后一个元素的下一个位置
private int[] arr;
public circleArrayQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
}
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
public boolean isEmpty() {
return rear == front;
}
//入队列
public void addQueue(int x) {
if (isFull()) {
System.out.println("队列已满,无法加入");
return;
}
arr[rear] = x;
rear = (rear + 1) % maxSize;
}
//出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空,无法获取");
}
int res = arr[front];
front = (front + 1) % maxSize;
return res;
}
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空,没有数据");
}
//从front开始遍历有效数据
for (int i = front; i < front + size(); i++) {
System.out.println("数组的显示为" + arr[i % maxSize] + " ");
}
}
//求出有效数据个数
public int size() {
return (rear + maxSize - front) % maxSize;
}
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法返回");
}
return arr[front % maxSize];
}
}
更多详情请关注菜鸟窝