赞
踩
1.队列是一个有序的列表,可以用数组或者链表来实现。
2. 队列存储数据的原则是:先进先出。
1. 队列本身就是一个有序的列表,如果要使用数组的结构来储存队列的数据。就要有以下声明:
maxSize 表示队列的最大容量。
2. 队列的输出输入分别从队列的前后端处理,定义队列的前端下标为front ,队列的下标为rear。
front会随着队列的输出而改变,rear会随队列的输入改变。
3. 当数据存入队列时,成为“add",add的处理步骤如下:
第一:当队列为空时,即front=rear, 将尾指针向后移动:rear+1。
第二:如果尾指针rear小于队列的最大下标maxSize-1,将数据存入到到rear所值的元素数组中,当rear=maxSize-1,
队列满了,无法存入数据。
- public class ArryQueue {
- //使用数组模拟队列
- private int maxSize;//表示队列的最大容量
- private int front;//队列的头
- private int rear;//队列的尾
- private int[] arr;//该数组用来存放数据,模拟队列
-
- //创建队列的构造器
- public ArryQueue(int arrMaxSize){
- maxSize=arrMaxSize;
- arr=new int[maxSize];
- front=-1;//指向队列头部,-1是指向头部的前一个位置,看图
- rear=-1;//指定队列尾,指向队列的尾的数据(就是队列的最后一个数据)
- }
- //判断队列是否满了
- public boolean isFull(){
- return rear==maxSize-1;
- }
- //判断队列是否为空
- public boolean isEmpty(){
- return rear==front;
- }
- //将数据插入到队列中
- public void addQueue(int n){
- if(isFull()){
- System.out.println("队列满了,不能加入数据");
- return;
- }
- rear++;//让rear向后移动
- arr[rear]=n;
- }
- //获取队列中的数据
- public int getQueue(){
- if(isEmpty()){
- //通过抛出异常
- throw new RuntimeException("队列为空,不能取出数据");
- }
- front++;//让front后移
- return arr[front];
- }
- //显示队列中的所有元素
- public void showQueu(){
- //遍历
- if(isEmpty()){
- System.out.println("队列空的,没有数据");
- return;
- }
- for (int i = 0; i < arr.length; i++) {
- System.out.printf("arr[%d]=%d\n",i,arr[i]);
- }
- }
- //显示队列的头数据,不是去除数据
- public int headQueu(){
- //判断
- if(isEmpty()){
- throw new RuntimeException("队列为空,不能取出数据");
- }
- return arr[front+1];
- }
-
-
- //测试
- public static void main(String[] args) {
- //创建一个队列
- ArryQueue queue=new ArryQueue(3);
- 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("g(get):从队列中去除数据");
- System.out.println("h(head):查看队列头的数据");
- key=scanner.next().charAt(0);//接受一个字符
- switch (key){
- case 's':
- queue.showQueu();
- break;
- case 'a':
- System.out.println("输入一个数");
- int value=scanner.nextInt();
- queue.addQueue(value);
- break;
- case 'g':
- try {
- int queue1 = queue.getQueue();
- System.out.printf("取出的数据为%d\n",queue1);
- }catch (Exception e){
- System.out.println(e.getMessage());
- }
- break;
- case 'h':
- try {
- int queue2 = queue.headQueu();
- System.out.printf("队列的头元素的数据为%d\n",queue2);
- }catch (Exception e){
- System.out.println(e.getMessage());
- }
- break;
- case 'e':
- //退出
- scanner.close();
- loop=false;
- break;
- default:
- break;
- }
- }
- System.out.println("程序退出");
- }
- }
现在的队列只能使用一次,就不能在重复使用,达不到复用的效果。
我们可以通过使用算法优化,改进成一个环形队列。
对上述代码进行优化,充分使用数组,因此可以将数组看成环形的。
1. 调整front的含义,front指向队列的第一个元素,arr [front] =第一个元素。此时front的初始值为0。
2. 调整real的含义,rear指向队列的最后一个元素的后一个位置(倒数第二个元素),因为我们想留出一个空间作为约 定。 rear的初始值为0.
3. 队列满的条件: (rear+1)%maxSize= front 。
4. 队列空的条件: rear == front 。
5. 队列有效数据的个数 (real + maxSize - front )% maxSize
- public class CirleQueueDemo {
- //使用数组模拟环形队列
- private int maxSize;//表示队列的最大容量
- private int front;//队列的头,指向队列的头
- private int rear;//队列的尾,指向队列的最后一个元素的后一个位置,希望留出一个空间作为约定
- private int[] arr;//该数组用来存放数据,模拟环形队列
-
- //创建队列的构造器
- public CirleQueueDemo(int arrMaxSize){
- maxSize=arrMaxSize;
- arr=new int[maxSize];
- //front=0;//指向队列头部,
- //rear=0;//指定队列尾,
- }
- //判断队列是否满了
- public boolean isFull(){
- return (rear+1)%maxSize==front;
- }
- //判断队列是否为空
- public boolean isEmpty(){
- return rear==front;
- }
- //将数据插入到队列中
- public void addQueue(int n){
- if(isFull()){
- System.out.println("队列满了,不能加入数据");
- return;
- }
- arr[rear]=n;
- //将rear后移,这里必须考虑取模
- rear=(rear+1)%maxSize;
- }
- //获取队列中的数据
- public int getQueue(){
- if(isEmpty()){
- //通过抛出异常
- throw new RuntimeException("队列为空,不能取出数据");
- }
- //1.先把元素取出来,存储到临时变量中
- int v=arr[front];
- //2 front后移,这时需要考虑取模
- front=(front+1)%maxSize;
- //3 将保存的变量返回
- return v;
- }
- //显示队列中的所有元素
- public void showQueu(){
- //遍历
- if(isEmpty()){
- System.out.println("队列空的,没有数据");
- return;
- }
- for (int i=front; i < front+size(); i++) {
- System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
- }
- }
- //得到当前队列中的有效数据的个数
- public int size(){
- return (rear+maxSize-front)%maxSize;
- }
- //显示队列的头数据,不是去除数据
- public int headQueu(){
- //判断
- if(isEmpty()){
- throw new RuntimeException("队列为空,不能取出数据");
- }
- return arr[front];
- }
-
-
- //测试
- public static void main(String[] args) {
- //创建一个队列
- CirleQueueDemo queue=new CirleQueueDemo(4);//设置为4,队列中的有效数据最大为3,留出了一个约定孔空间
- 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("g(get):从队列中去除数据");
- System.out.println("h(head):查看队列头的数据");
- key=scanner.next().charAt(0);//接受一个字符
- switch (key){
- case 's':
- queue.showQueu();
- break;
- case 'a':
- System.out.println("输入一个数");
- int value=scanner.nextInt();
- queue.addQueue(value);
- break;
- case 'g':
- try {
- int queue1 = queue.getQueue();
- System.out.printf("取出的数据为%d\n",queue1);
- }catch (Exception e){
- System.out.println(e.getMessage());
- }
- break;
- case 'h':
- try {
- int queue2 = queue.headQueu();
- System.out.printf("队列的头元素的数据为%d\n",queue2);
- }catch (Exception e){
- System.out.println(e.getMessage());
- }
- break;
- case 'e':
- //退出
- scanner.close();
- loop=false;
- break;
- default:
- break;
- }
- }
- System.out.println("程序退出");
- }
数组模拟队列2:
- package Queue.VirtulQueue;
-
- import java.util.ArrayList;
-
- public class ArrayQueuedemo {
- public static void main(String[] args) {
- ArrayQueue arrayQueue=new ArrayQueue<Integer>();
- arrayQueue.inQueue(1);
- arrayQueue.inQueue(2);
- arrayQueue.inQueue(3);
- arrayQueue.inQueue(4);
- arrayQueue.inQueue(5);
- System.out.println("队中的元素个数"+arrayQueue.size());
- System.out.println("队中的首元素"+arrayQueue.firstQueue());
- System.out.println("队中的尾元素"+arrayQueue.lastQueue());
- arrayQueue.outQueue();
- arrayQueue.outQueue();
- System.out.println("队中的元素个数"+arrayQueue.size());
- System.out.println("队中的首元素"+arrayQueue.firstQueue());
- System.out.println("队中的尾元素"+arrayQueue.lastQueue());
- }
- }
- class ArrayQueue<T>{
- private ArrayList<T> array=new ArrayList<T>();//成员变量 array 来存储元素怒
- private int front;//成员变量,指向队列的首位置
- private int real;//成员变量,指向队列尾元素的下一个位置。
-
- public ArrayQueue() {
- front=0;
- real=0;
- }
- //判断队列是否为空
- Boolean Empty(){
- return front==real;
- }
- //入队
- void inQueue(T item){
- array.add(item);
- real++;
- }
- //查看队列的大小
- int size(){
- return real-front;
- }
- //查看队列的首元素
- T firstQueue(){
- if (Empty()){
- return null;
- }
- return array.get(front);
- }
- //查看队列的尾元素
- T lastQueue(){
- if (Empty()){
- return null;
- }
- return array.get(real-1);
- }
- //出队
- void outQueue(){
- if (real>front){
- front++;
- }else {
- System.out.println("队列为空");
- }
-
- }
- }
链表模拟队列
- package Queue.VirtulQueue;
-
- public class ListQueue {
- public static void main(String[] args) {
- Queue<Integer> queue=new Queue<Integer>();
- queue.inQueue(1);
- queue.inQueue(2);
- queue.inQueue(3);
- queue.inQueue(4);
- queue.inQueue(5);
- System.out.println("队列的大小"+queue.size());
- System.out.println("队列的首元素"+queue.fqueue());
- System.out.println("队列的尾元素"+queue.lqueue());
- queue.outQueue();
- System.out.println("队列的大小"+queue.size());
- System.out.println("队列的首元素"+queue.fqueue());
- System.out.println("队列的尾元素"+queue.lqueue());
- }
- }
- class Queue<T>{
- private LNode<T> head;//定义链表的头结点,指向队列的头
- private LNode<T> end;//定义链表的尾结点,指向队列的尾
-
- //构造函数,一开始初始化队列为空
- public Queue() {
- head=end=null;
- }
-
- //队列是否为空
- Boolean Empty(){
- return head==null;
- }
-
- //入队
- void inQueue(T item){
- LNode<T> tmp=new LNode<>();
- tmp.data=item;
- tmp.next=null;
- if (head==null){
- head=end=tmp;
- }else {
- end.next=tmp;
- end=tmp;
- }
-
- }
- //队列元素的个数
- int size(){
- int i=0;
- LNode<T> tmp=head;
- while (tmp!=null){
- tmp=tmp.next;
- i++;
- }
- return i;
- }
- //出队
- void outQueue(){
- if (Empty()){
- System.out.println("队列为空");
- }
- head=head.next;
- if (head==null){
- end=null;
- }
- }
- //队列的首元素
- T fqueue(){
- if (Empty()){
- System.out.println("队列为空");
- return null;
- }
- return head.data;
- }
- //队列的尾
- T lqueue(){
- if (end==null){
- System.out.println("队列为空");
- return null;
- }
- return end.data;
- }
- }
-
- class LNode<T>{
- T data;
- LNode<T> next;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。