前言:笔记是参考B站up主尚硅谷,图片、代码都是哦。因为最近特别喜欢他教的课程,所以就一边跟着学习,一边在blog写笔记~(图片、代码来源尚硅谷,侵权必删!)
尚硅谷数据结构学习路线B站网站:https://www.bilibili.com/video/BV1E4411H73v
线性结构和非线性结构
常见的线性结构:数组(稀疏数组)、队列(单项队列、环形队列)、链表(单链表、环形链表、双链表)、栈(数组实现或链表实现)。
常见的非线性结构:二维数组、多维数组、广义表、树结构、图结构
队列
队列是一个有序列表,可以用数组或是链表来实现。
遵循先进先出的原则。
public class ArrayQueueDemo {
public static void main(String[] args) {
//创建一个队列
ArrayQueue arrayQueue = new ArrayQueue(3);
arrayQueue.addQueue(5);
arrayQueue.addQueue(44);
arrayQueue.addQueue(341);
arrayQueue.showQueue(); //显示队列数据
System.out.println(arrayQueue.headQueue()); //未取出数据,所以队列头是5
arrayQueue.getQueue(); //取5 出队列
System.out.println(arrayQueue.headQueue()); //5被移除队列,所以队列头是44
arrayQueue.getQueue(); //取44 出队列
System.out.println(arrayQueue.headQueue()); //44被移除队列,所以队列头是341
arrayQueue.getQueue(); //取341 出队列
System.out.println(arrayQueue.headQueue()); //341被移除队列,报异常直接return
}
}
//使用数组来模拟队列
class ArrayQueue{
private int maxSize; //数组(队列)最大容量
private int front; //队列头部
private int rear; //队列尾部
private int[] arr; //存放数据 模拟队列
//创建队列的构造器
public ArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[maxSize];
front = -1; //指向队列头部(指向下标0的前一个位置)
rear = -1; //指向队列尾部 就是最后一个数据
}
//判断队列是否满 如maxSize = 3;rear = 2(下标从0开始),则这个队列满!
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 showQueue(){
//判断是否空
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 headQueue(){
if (isEmpty()){
throw new RuntimeException("队列空!");
}
return arr[front + 1];
}
}
输出结果:
arr[0]=5
arr[1]=44
arr[2]=341
5
44
341
Exception in thread "main" java.lang.RuntimeException: 队列空!
at ArrayQueue.headQueue(ArrayQueueDemo.java:81)
at ArrayQueueDemo.main(ArrayQueueDemo.java:15)
Process finished with exit code 1
使用数组模拟队列存在的问题:
数组用一次,就不能用了,也就是说取出数据后,再插入数据是插入不了的,会提示队列满!没有达到复用的效果。
优化:
将这个数组使用算法,改进成一个环形的队列 % 取模的方式。
使用环形队列(优化取出数据后位置占满问题)
public class CircleArrayQueueDemo {
public static void main(String[] args) {
//创建一个队列
CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4); //设置4,实际队列有效数据最大是3 --> 0,1,2 因为需要空出一个位置。
circleArrayQueue.addQueue(5);
circleArrayQueue.addQueue(44);
circleArrayQueue.addQueue(341);
circleArrayQueue.showQueue(); //显示队列数据
System.out.println("未取出时,第一个头部数据是:"+circleArrayQueue.headQueue()); //未取出数据,所以队列头是5
circleArrayQueue.getQueue(); //5 出队列
System.out.println("取出5后,第一个头部数据变成:"+circleArrayQueue.headQueue()); //5已经被移除队列,所以队列头是44
circleArrayQueue.addQueue(555);
circleArrayQueue.showQueue(); //显示队列数据
circleArrayQueue.getQueue(); //44 出队列
System.out.println("取出44后,第一个头部数据变成:"+circleArrayQueue.headQueue()); //44已经被移除队列,所以队列头是341
circleArrayQueue.addQueue(12);
circleArrayQueue.showQueue(); //显示队列数据
}
}
//使用数组来模拟队列
class CircleArrayQueue {
private int maxSize; //数组(队列)最大容量
private int front; //默认为0
private int rear; //默认为0 rear指向队列的最后一个元素的后一个位置 因为希望空出一个空间作为约定
private int[] arr; //存放数据 模拟队列
//创建队列的构造器
public CircleArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[maxSize];
}
//判断队列是否满
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+1) % maxSize; //将rear后移,必须考虑取模
}
//取出队列的第一个数据,出队列
public int getQueue(){
//判断队列是否空
if (isEmpty()){
//抛出异常
throw new RuntimeException("队列空");
}
//这里需要分析出front是指向队列的第一个元素
//1.先把front对应的值保存到一个临时变量
//2.将front后移
//3.将临时保存的变量返回
int value = arr[front];
front = (front+1) % maxSize;
return value;
}
//显示队列数据
public void showQueue(){
//判断是否空
if (isEmpty()){
System.out.println("队列空");
return;
}
for (int i = 0;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 headQueue(){
if (isEmpty()){
throw new RuntimeException("队列空!");
}
return arr[front];
}
}
输出结果:
arr[0]=5
arr[1]=44
arr[2]=341
未取出时,第一个头部数据是:5
取出5后,第一个头部数据变成:44
arr[0]=5
arr[1]=44
arr[2]=341
arr[3]=555
取出44后,第一个头部数据变成:341
arr[0]=12
arr[1]=44
arr[2]=341
arr[3]=555
arr[0]=12
Process finished with exit code 0