常识:
声明是指使用一个对象的时候,先定义属于哪个类型并,比如string _str;
_str是声明(定义)了一个string类型的对象。
初始化可以理解为给声明的对象赋值的过程。string _str =“hello”;
_str现在已经被初始化了,实例化后它具有“hello”这个值。
实例化是类用到的,A a = new A();当new的时候为对象分配内存,这个过程是对象的实例化。
总结:
声明,只生成对象不赋值的过程。
初始化,是给对象赋值的过程。
实例化,是使用new为对象分配内存的过程。
(一)队列
1. 什么是队列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-piaLJwG7-1587910938594)(D:\e\youdaonote\qq93FD1002CEBEDBA1C4904928ED0FA5B3\3013ab4bc5b84d73bc87cba39059479c\clipboard.png)]
front随着数据的输出改变,rear随着数据的输入改变
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cFvhuI1K-1587910938596)(C:\Users\lzp\AppData\Roaming\Typora\typora-user-images\image-20200426204044305.png)]
### 2.队列的一些操作
#### 2.1 加入数据和取数据
数组实现思路:
rear是尾指针,front是头指针
- 首先将尾指针往后移 :rear +1,因为要先开辟空间存数据,你不往后移动,没有空间放数据。
需要提前判断队列是不是空,front == rear 如果相等,说明队列是空。
-
如果尾指针 rear==maxSize - 1说明尾指针已经指向了这个队列的最后,队列已满。
-
如果尾指针rear < maxSize -1 , 说明 可以往队列里面存值。
代码实现
package com.lzp.datastructure.study.Day2Queue; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import java.util.Scanner; import java.util.concurrent.ExecutionException; /** * 2020-4-5 * @Author lzp * 数组模拟队列队列 缺点:没有做成环形队列,当加入数据加满,然后再全部取出,rear还是=maxSize - 1 ,无法再加入数据,数组只能用一次 */ public class ArrayQueueDemo { public static void main(String[] args) { // 测试一波 //创建一个队列 ArrayQueue arrayQueue = new ArrayQueue(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': arrayQueue.showQueue(); break; case 'a': System.out.println("请输入一个数字"); int value = scanner.nextInt(); arrayQueue.addQueen(value); arrayQueue.showQueue(); break; case 'g' ://去除数据 try { int res = arrayQueue.getQueen(); System.out.printf("取出的数据是%d\n",res); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'h': try { int res = arrayQueue.hearQueue(); System.out.printf("队列头的数据是%d\n",res); }catch (Exception e){ System.out.println(e.getMessage()); } break; case 'e'://退出程序 scanner.close(); loop = false; break; default: break; } } System.out.println("成功退出程序"); } } //使用数组编写一个 ArrayQueue类 class ArrayQueue{ private int maxSiez; private int front; private int rear; private int[] arr; //该数组 用于存放数据,模拟队列 //创建队列的构造器 如果使用队列,一上来new的时候就会确定队列对象的大小 public ArrayQueue(int arrMaxSize){ maxSiez =arrMaxSize; arr = new int[maxSiez]; front = -1; //队列第一个角标是0,这里的font 指向队列第一个数据之前。 rear = -1; //指向队列的最后一个数据,注意: 不是指向最后一个数据之后。rear = 0 ,说明rear指向了角标为零的数据。 } //判断队列是否为满 public boolean isFull(){ return rear == maxSiez -1; } //判断队列是否为空 public boolean isEmpty(){ return front==rear; } //添加数据到队列 public void addQueen(int n){// n是你传入的一个 int型数据。 //判断队列是否满 if(isFull()){ System.out.println("队列已经满了"); return; } //如果没有满,那么在往队列里面加入数据之前,需要先把rear 往后移动一位 q: 为什么不是移动好几位?front可以大于rear 吗? rear++; //创建一个数组 ,把数据放入。 arr[rear] = n; } //获取到数据 感觉每次获取一次,队列的长度就会变小 front自增是因为front自己不是指向头部,是指向头部的前一个位置 // 0 1 2 3 public int getQueen(){ //判断队列是否为空 if(isEmpty()){ //抛出异常 throw new RuntimeException("队列已经空,无法取到数据");//执行到这行,throw 就会return,throw下面的代码就已经无法执行了。 } return arr[++front]; //front后移一位,然后返回出去。 队列是从头部返回数据的。如果是栈,估计是从尾部? } //显示队列的所有数据 public void showQueue(){ //遍历 if(isEmpty()){ System.out.println("队列空的,没有数据"); return; } System.out.println("输出队列"); for (int i = 0; i < arr.length; i++) { System.out.printf("arr[%d]=%d\n",i,arr[i]); } } // 显示队列的头数据 不是取数据 因为这是队列,所以头数据有特殊含义,因为队列取数据永远都是从取头数据的。 public int hearQueue(){ //判断 if(isEmpty()){ throw new RuntimeException("队列为空"); } return arr[front+1]; } }