图解&代码实现:数组模拟实现环形队列
2020-01-13 18:20
666 查看
数组模拟实现环形队列
实现:让数组达到复用的效果,即:当我们从数组队列中取出了数据,那取出数据后后这个空间可以再次使用
数组秒实现环形队列的思路分析
当
rear指针指向
maxsize - 1时,也就是当
rear = maxsize - 1时,需要判断
rear的前面是否有空闲空间,也就是说front是否产生了变化并且已经不在初始的那个位置了
思路如下:
-
front的含义做调整 :front由原来的指向队列头的前一个位置调整为现在的front指向了队列头
队列头:就是队列中第一个数据所在的位置
即:
queueArr[front]
就是获取的队列中的第一个数据
说明:
-
原来front的初始值为 - 1 现在 front 的初始值为0
-
原来的front是不包含队列头的,现在的front是包含队列头的
-
rear的含义做调整:rear从原来指向队列的最后一个数据调整为了现在的rear指向队列的最后一个数据的前一个位置
调整rear的目的:预留一个空间作为约定
说明:
-
原来的rear的初始值为 - 1,现在的rear的初始值为0
-
原来的rear包含队列的最后一个数据,现在的rear是不包含队列的最后一个数据。
-
预留的空间是动态变化的,预留空间始终都在rear指向的
最后一个数据
的后一个位置 -
rear和front含义发生调整后,判断队列满的条件是
( rear + 1 )% maxsize = front
为什么要取模? 答:因为rear可能是一直增长的,从而达到数组空间复用的效果
原先队列满的条件是
rear = maxsize - 1
因为 原先没有考虑数组空间的复用
4. 判断队列为空的条件是rear = front
-
经过以上分析,当rear和front含义发生调整后,队列中有效数据的个数 是
(rear + maxsize - front) % maxsize
为什么要取模?答:因为是环形队列,rear有可能指到队列最前面。
打个比方,当
rear = 0,maxsize = 4 ,front = 0
时,该队列中有多少个有效的数据?
分析:(0 + 3 - 0)% 3 = 0,该队列中有效的数据个数为0个,因为rear = front ,则证明是空队列
-
使用代码来实现“数组模拟实现环形队列”
代码展示:
public class CirCleQueueArrayTest{ public static void main(String[] agrs){ // 实例化CirCleArrayQueue CirCleQueueArray cirCleArrayQueue = new CirCleQueueArray(3); char key = ' '; boolean flag = true; java.util.Scanner input = new java.util.Scanner(System.in); while(flag){ System.out.println("s(showQueue()) : 显示队列中的所有数据"); System.out.println("g(getQueue()) : 把数据从队列中取出来"); System.out.println("a(addQueue(int num)) : 把数据添加到队列中"); System.out.println("h (headQueue()) : 查看队列中的第一个数据"); System.out.println("i(size()) : 显示队列中的有效数据的个数"); System.out.println("e(exit) : 退出程序"); System.out.print("请选择:"); key = input.next().charAt(0); switch(key){ case 's': cirCleArrayQueue.showQueue(); break; default: break; case 'e': flag = false; break; case 'i': try{ System.out.println("队列中有效数据的个数为 " + cirCleArrayQueue.size()); }catch(Exception e){ System.out.println(e.getMessage()); } break; case 'a': System.out.print("请输入一个数:"); int num = input.nextInt(); cirCleArrayQueue.addQueue(num); break; case 'g': try{ cirCleArrayQueue.getQueue(); }catch(Exception e){ System.out.println(e.getMessage()); } break; case 'h': try{ System.out.println( "队列的第一个数据为 " + cirCleArrayQueue.headQueue()); }catch(Exception e){ System.out.println(e.getMessage()); } break; } } System.out.println("程序正常退出~~~"); } } class CirCleQueueArray{ // 编写属性(共4个) // rear 调整后的含义为:指向队列中的最后一个数据的前一个位置 ,rear 的初始值为0 private int rear; // front 调整后的含义为: 指向队列头(即:队列中的第一个数据),front的初始值为 0 private int front; // queueArr : 队列数组,数组模拟实现环形队列 private int queueArr[]; // maxsize 表示队列的最大容量,队列中的数据是存放在数组中的 private int maxsize; // 编写无参构造 public CirCleQueueArray(){ } // 编写带参构造,实现将局部变量maxsize的值赋值给成员变量maxsize 并对queueArr[]进行初始化 public CirCleQueueArray(int maxsize){ // 将局部变量maxsize的值赋值给成员变量maxsize this.maxsize = maxsize; // 对queueArr[]进行初始化 queueArr = new int[maxsize]; } // 编写成员方法,判断队列是否为空isEmpty() public boolean isEmpty(){ return rear == front; } // 编写成员方法,判断队列是否已满isFull() public boolean isFull(){ return (rear + 1) % maxsize == front; } // 编写成员方法 ,求出队列中有效数据的个数 public int size(){ if(isEmpty()){ throw new RuntimeException("数组为空,没有有效数据"); } return (rear + maxsize - front) % maxsize; } // 编写成员方法,实现入队列addQueue(int num),无返回值类型带参 public void addQueue(int num){ if(isFull()){ System.out.println("队列已满,不能实现入队列"); return; } // 直接将数据加入 queueArr[rear] = num; // 将rear 指针后移,必须考虑到取模 rear = (rear + 1) % maxsize; } // 编写成员方法,实现出队列getQueue(),有返回值无参 public int getQueue(){ if(isEmpty()){ throw new RuntimeException("空队列,不能实现出队列"); } // 第一步 先把queueArr[front]对应的保存在一个临时变量中 // 为什么要将queueArr[front]对应的保存在一个临时变量中? 因为 若直接返回的话,就没有往后移的机会了 int tempValue = queueArr[front]; // 第二步 将front后移,考虑取模 front = (front + 1) % maxsize; // 将临时变量中的值返回 return tempValue; } // 编写成员方法,通过for循环 | 增强for循环遍历队列中的所有的数据 public void showQueue(){ if(isEmpty()){ System.out.println("队列为空,不能遍历队列"); return ; } for(int i = front;i < front + size();i ++){ System.out.println("queueArr["+ i % maxsize +"] = " + queueArr[i % maxsize]); } } // 编写成员方法,显示队列头 (即:队列中的第一个数据) public int headQueue(){ if(isEmpty()){ throw new RuntimeException("空队列,无法查看"); } return queueArr[front]; } }
总结:
- 环形队列判满条件:
(rear +1) % maxsize == front
- 环形队列判空条件:
rear == front
- 环形队列有效数据的个数
(rear + maxsize - front) % maxsize
- 环形队列中rear的含义:指向队列中最后一个数据的前一个位置,因为要预留一个空间作为约定
- 环形队列中front的含义:指向队列头(即:队列中的第一个数据)
- 点赞 1
- 收藏
- 分享
- 文章举报
相关文章推荐
- 数组模拟队列思路分析及代码实现
- 数组实现环形队列
- 环形队列的数组实现
- c语言数据结构实现-数组队列/环形队列
- golang环形队列实现代码示例
- 队列的顺序存储结构——循环队列 图解和代码实现
- 无锁队列的环形数组实现(Lock Free Queue Implementation in Ring Array)
- 数据结构循环队列——数组模拟实现
- 常见对象_数组高级冒泡排序原理图解、数组高级冒泡排序代码实现
- 无锁队列的环形数组实现
- javascript中利用数组实现的循环队列代码
- javascript中利用数组实现的循环队列代码
- 用数组实现栈(Stacks)、队列(Queue)和双向链表(Doubly Linked List)的伪代码
- 程序员面试题精选(48):两个堆栈模拟队列c++代码实现
- 队列的底层实现(数组和环形数组)
- 栈、队列(详细图解与代码实现)
- 【模拟】【环形数组】-UVA-133- The Dole Queue |java实现
- 数组模拟队列的实现
- 队列的顺序存储结构——循环队列 图解和代码实现
- java数组实现队列及环形队列实现过程解析