数组实现队列:
一、实现普通队列
1) 将尾指针往后移:rear+1 , 当 front == rear 【空】
2) 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。rear == maxSize - 1[队列满]
public static void main(String[] args) {
ArrayCircleQueue mArrayQueueTest = new ArrayCircleQueue(5);
Scanner scanner = new Scanner(System.in);
char key = ' '; //接收用户输入
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): 查看队列头的数据");
key = scanner.next().charAt(0);//接收一个字符
switch (key) {
case 's':
mArrayQueueTest.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
mArrayQueueTest.addQueue(value);
break;
case 'g': //取出数据
try {
int res = mArrayQueueTest.getQueue();
System.out.printf("取出的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看队列头的数据
try {
int res = mArrayQueueTest.peek();
System.out.printf("队列头的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'e': //退出
scanner.close();
loop = false;
break;
default:
break;
}
}
}
/**
1. 数组实现单项队列
2. 1) 将尾指针往后移:rear+1 , 当 front == rear 【空】
3. 2) 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。
4. 3) 判断队列 满没满 end == mMaxSize - 1
5. 头指针在队列的前一个位置。是这么设计的(你也可以放在当前头的位置)
*/
static class ArrayQueueTest{
// 头指针
public int head = -1;
// 尾指针
public int end = -1;
// 队列
public int[] mQueue;
// 队列的最大容量
public int mMaxSize;
public ArrayQueueTest(int mMaxSize) {
this.mMaxSize = mMaxSize;
mQueue = new int[mMaxSize];
}
/**
* 添加数据
*/
public void addQueue(int data){
if(isFull()) {
System.out.print("队列已经满了");
return;
}
// 尾指针往后加
end++;
mQueue[end] = data;
}
/**
* 取数据
*/
public int getQueue(){
if(isEmpty()) {
throw new RuntimeException("队列为空哦~~~");
}
// 头指针往后移
head++;
return mQueue[head];
}
/**
* 查看头数据
*/
public int peek(){
if(isEmpty()) {
throw new RuntimeException("队列为空哦~~~");
}
return mQueue[head + 1];
}
/**
* 遍历数组
*/
public void showQueue(){
if(isEmpty()) {
System.out.println("队列空的,没有数据~~");
return;
}
for(int i = 0; i < mQueue.length; i++) {
System.out.println(i+" ------> "+mQueue[i]);
}
}
/**
* 判断队列是否为空
* @return
*/
public boolean isEmpty(){
return head == end;
}
/**
* 判断队列满没满
*/
public boolean isFull(){
return end == mMaxSize - 1;
}
}
二、实现环形队列
分析说明:
1、尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定,这个在做判断队列满的时候需要注意 (rear + 1) %maxSize == front 满]
2、 rear == front [空]
3、为什么要预留一个空间呢?因为这样比较好判断是不是满了,是不是空(若不使用空节点。当font-rear=-1时,不能判断是空还是满.这时可能会多一些处理语句。比如:在出队列时,如果发现font=rear的情况。在出队列以后将font=rear=-1.判断为空的唯一条件就是font=rear=-1)
4、分析示意图:
public static void main(String[] args) {
ArrayCircleQueue mArrayQueueTest = new ArrayCircleQueue(5);
Scanner scanner = new Scanner(System.in);
char key = ' '; //接收用户输入
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): 查看队列头的数据");
key = scanner.next().charAt(0);//接收一个字符
switch (key) {
case 's':
mArrayQueueTest.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
mArrayQueueTest.addQueue(value);
break;
case 'g': //取出数据
try {
int res = mArrayQueueTest.getQueue();
System.out.printf("取出的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看队列头的数据
try {
int res = mArrayQueueTest.peek();
System.out.printf("队列头的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'e': //退出
scanner.close();
loop = false;
break;
default:
break;
}
}
}
/**
* 数组实现环形队列
* *) 队列尾部空余一个空间
* 1)判断队列满没满 (end + 1 )% size == head 尾指针+ 1(预留空间) % size == 头指针说明数组满了
* 2)判断队列有效个数 (end + size - head) % size
*/
static class ArrayCircleQueue{
// 头指针
public int head;
// 尾指针
public int end;
// 队列
public int[] mQueue;
// 队列的最大容量
public int mMaxSize;
public ArrayCircleQueue(int mMaxSize) {
this.mMaxSize = mMaxSize;
mQueue = new int[mMaxSize];
}
/**
* 添加数据
*/
public void addQueue(int data){
if(isFull()) {
System.out.print("队列已经满了");
return;
}
mQueue[end] = data;
// 尾指针计算
end = (end + 1) % mMaxSize;
}
/**
* 取数据
*/
public int getQueue(){
if(isEmpty()) {
throw new RuntimeException("队列为空哦~~~");
}
// 头指针往后移
int value = mQueue[head];
head = (head + 1) % mMaxSize;
return value;
}
/**
* 查看头数据
*/
public int peek(){
if(isEmpty()) {
throw new RuntimeException("队列为空哦~~~");
}
return mQueue[head];
}
// 显示队列的所有数据
public void showQueue() {
// 遍历
if (isEmpty()) {
System.out.println("队列空的,没有数据~~");
return;
}
// 思路:从front开始遍历,遍历多少个元素
for (int i = head; i < head + size() ; i++) {
System.out.printf("arr[%d]=%d\n", i % mMaxSize, mQueue[i % mMaxSize]);
}
}
// 求出当前队列有效数据的个数
public int size() {
// rear = 2
// front = 1
// maxSize = 3
return (end + mMaxSize - head) % mMaxSize;
}
/**
* 判断队列是否为空
* @return
*/
public boolean isEmpty(){
return head == end;
}
/**
* 判断队列满没满
*/
public boolean isFull(){
return head == (end + 1) % mMaxSize;
}
}