队列是一个有序列表,可以由数组或者链表实现
数据先入先出
⭐⭐:写程序之前一定要先把需求写在纸上,然后在下笔
单向队列
public class singlequeue {
private int maxSize ;
private int head = 0; // 指向下一个弹出的元素索引
private int tail = 0; // 指向下一个要存放数据的索引
private int[] arr ; // 模拟队列
public singlequeue(int size){
if (size < 1){
throw new RuntimeException("size must > 0");
}
maxSize = size;
arr = new int[size];
}
public boolean empty(){
return head == tail; // 下一个要弹出的索引 == 下一个存放数据的索引
}
// 最大 tail = maxSize - 1;
public boolean full(){
return tail == maxSize; // 下一个要存放数据的索引 【超过了可以存放的范围】
}
// 当前队列最大容量
public int cap(){
return maxSize;
}
// 还可以存放多少个元素
public int size(){
return maxSize - tail;
}
// 入队: 先要判断有没有位置存放, 然后tail就是可以存放的位置
public void push(int ele){
if (full()){
throw new RuntimeException("当前队列已经满了");
}
arr[tail++] = ele; // 存放位置,然后tail++
}
// head和tail之间一定要有元素才能出队
public void pop(){
if (empty() || head > maxSize - 1){
throw new RuntimeException("空队列, 不能取元素");
}
arr[head++] = 0;
}
public void printQueue(){
if (empty()){
throw new RuntimeException("空队列, 不能取元素");
}
for (int i = head; i < tail; i++){ // tail为下一个元素的放置位置,当前还没有元素
System.out.printf("%d\t", arr[i]);
}
System.out.println();
}
}
import java.util.Scanner;
public class arrayqueue {
public static void main(String[] args) {
singlequeue q = new singlequeue(5);
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("d(delete):出队一个元素");
key = scanner.next().charAt(0);
switch (key){
case 's':
q.printQueue();
System.out.println(q.size());;
break;
case 'e':
loop = false;
break;
case 'a':
int t = scanner.nextInt();
q.push(t);
break;
case 'd':
q.pop();
break;
}
}
}
}
问题分析:目前数组使用依次就不能用,没有达到复用的效果
优化:循环队列
循环队列
public class circlequeue {
private int head = 0; // 尾索引: 指向下一个要取出的位置索引
private int tail = 0; // 头索引: 指向下一个要放的位置索引
private int count = 0; // 当前队列元素个数
private int maxsize = 0; //队列多大
private int [] arr;
public circlequeue(int cap){
maxsize = cap;
arr = new int[cap];
}
public void printQueue(){
int t = head;
for (int i = 0; i < count; i++){
t = head + i; // 指向下一个要取出的位置索引
if (t == maxsize){
t = 0;
}
System.out.printf("%d\t", arr[t]);
}
System.out.println();
}
// 还有多少个位置
public int size(){
return maxsize - count;
}
//也就是取出来的位置和放置位置相同,但是放置位置还米有元素,说明当前队列为空
public boolean empty(){
return count == 0;
}
// 存放元素个数 = 数组长度,满了
// ( head + 1 ) % maxSize
public boolean full(){
return count == maxsize;
}
public void push(int ele){
if (full()){
throw new RuntimeException("当前队列已满");
}
// 本次
arr[tail] = ele;
count++;
// tail为下一次放置位置, 如果超出了索引,重新开始
/* tail++;
if (tail == maxsize){
tail = 0;
}*/
tail = (tail + 1) % maxsize;
}
public void pop(){
if (empty()){
throw new RuntimeException("队列为空");
}
arr[head] = 0;
count--;
/*
head++;
if (head == maxsize){
head = 0;
}
*/
head = (head + 1) % maxsize;
}
}
import java.util.Scanner;
public class arrayqueue {
public static void main(String[] args) {
circlequeue q = new circlequeue(5);
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("d(delete):出队一个元素");
key = scanner.next().charAt(0);
switch (key){
case 's':
q.printQueue();
System.out.println(q.size());;
break;
case 'e':
loop = false;
break;
case 'a':
int t = scanner.nextInt();
q.push(t);
break;
case 'd':
q.pop();
break;
}
}
}
}
https://www.cs.usfca.edu/~galles/visualization/QueueArray.html