近期学习数据结构笔记=====>队列
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了近期学习数据结构笔记=====>队列相关的知识,希望对你有一定的参考价值。
学习来源–>传送门–>尚硅谷Java数据结构与java算法(Java数据结构与算法)
队列:先进先出结构
是有序的列表; 可以用数组/链表存储数据;
例如->数组存储结构; maxSize:最大容量;
对于数组存储的话,就考虑数组的索引问题,数组是由0索引开始的,那么实际上这个队列在 (maxSize -1)的时候就满了;
在向队列存储数据的时候,首先要考虑判断队列是否满了;添加后队列的个数要增加1个;
删除的时候还要考虑让队列的元素个数减少1个;
队列为空的情况–> 头指针和尾指针 相等时;
数组模拟队列实现
package day02forqueue;
import java.util.Arrays;
/**
* @author by CSDN@小智RE0
* @date 2021-10-30 22:15
* 用队列模拟实现数组;
*/
public class QueueByArray {
//队列的容量;
private final int capacity;
//头部指针,实际指向队头的前一个位置;
private int front;
//尾巴指针;实际指向队列的最后一个位置;
private int rear;
//用数组存储数据;
private final int[] dataArray;
//初始化;指定容量;
public QueueByArray(int capacity) {
this.capacity = capacity;
this.front = -1;
this.rear = -1;
this.dataArray = new int[capacity];
}
//判断队列是否为空;
public boolean isEmpty(){
//头指针和尾指针在一块时,队列就是空的;
return front == rear;
}
//判断队列满了没; 尾指针指向最后一个时;就满了;
public boolean isFull(){
return rear == capacity - 1;
}
//添加元素进队列;
public void addQueue(int data){
//先判断队列是否满了;
if(isFull()){
System.out.println("队列已满,拒绝入队");
return;
}
//尾指针向后移动;
rear ++;
dataArray[rear] = data;
}
//模拟元素出队; 实际上元素还在 获取到队列的数据;
public int removeQueue(){
//先判断队列为空吗;抛出异常;
if(isEmpty()){
throw new RuntimeException("队列为空,拒绝获取");
}
//头指针后移;
front++;
return dataArray[front];
}
//输出队列;
public void toGetAll(){
//判空;
if(isEmpty()){
System.out.println("空队列,拒绝遍历");
return;
}
Arrays.stream(dataArray).forEach(System.out::println);
}
//获取队头;
public int getHead(){
//判空;
if(isEmpty()){
throw new RuntimeException("空队列,拒绝取元素");
}
return dataArray[front+1];
}
}
测试;
public static void main(String[] args) {
QueueByArray queueByArray = new QueueByArray(5);
queueByArray.addQueue(12);
queueByArray.addQueue(15);
queueByArray.addQueue(6);
queueByArray.addQueue(7);
queueByArray.addQueue(8);
//已经添加5个了;拒绝添加;
//queueByArray.addQueue(3);
//仅获取数据; 看着是被取走了;只是指针后移了而已;
System.out.println("获取数据->"+queueByArray.removeQueue());
//获取队头;
System.out.println("队头->"+queueByArray.getHead());
//遍历
queueByArray.toGetAll();
}
/*
获取数据->12
队头->15
12
15
6
7
8
*/
上面的队列,虽然说有基础的功能,但是还是有很大问题的;比如说它并不会真正地删除数据;
模拟环形队列实现
为了达到队列的复用;
指针的含义改变一下;
头指针就指定指向队列的头元素;
尾指针指向队尾的后一个位置; 为什么不是直接指向最后一个位置呢;
这是个环形的队列,尾指针有可能会跑前面来;
队满的判断条件也要改变;
当 (尾指针 +1 ) % 容量 == 头指针 ;
此时队列的有效数据个数; (尾指针 + 容量 - 头指针) % 容量;
注意有效数据的个数会比真实容量少一个
package day02forqueue;
/**
* @author by CSDN@小智RE0
* 模拟环形队列
*/
public class CircleQueueByArray {
// 容量,头指针,尾指针,数据容器;
private int capacity;
private int front;
private int rear;
private int[] dataArray;
//初始化;略有不同;
public CircleQueueByArray(int capacity) {
this.capacity = capacity;
dataArray = new int[capacity];
this.front = 0;
this.rear = 0;
}
//判空;
public boolean isEmpty(){
return front == rear;
}
//是否满队列;
public boolean isFull(){
return (rear + 1)%capacity == front;
}
//入队操作;
public void addQueue(int data){
//判断是否满;
if(isFull()){
System.out.println("队列已满,不能入队");
return;
}
//正常入队;
dataArray[rear] = data;
//尾指针后移;注意这是环形队列;
rear = (rear+1) % capacity;
}
//取出数据元素;
public int getData(){
//先判空;
if(isEmpty()){
throw new RuntimeException("队列为空,无法取出元素");
}
//正常取出; 注意要先把头指针指向的值存起来后再取出;
// 由于是环形队列,需要考虑到头指针转一圈可能还会回来; 所以不能直接让它++后移;
int temp = dataArray[front];
front = (front+1)%capacity;
return temp;
}
//获取队列的实际元素个数; 注意实际元素个数会比 容量少一个 ; 比如说创建了5个长度的,实际最多只能存放四个;
public int getSize(){
return (rear + capacity - front ) % capacity;
}
//遍历;
public void toGetAll(){
//判空;
if(isEmpty()){
System.out.println("空队列,拒绝遍历");
return;
}
//这里就要算有效元素的个数了;
for (int i = front; i <front+getSize() ; i++) {
System.out.printf("dataArray[%d]=%d\\n",i % capacity ,dataArray[i % capacity]);
}
}
//获取头元素;
public int getHead(){
//判空;
if(isEmpty()){
throw new RuntimeException("队列为空,不可取");
}
//取到即可;
return dataArray[front];
}
}
测试使用
public static void main(String[] args) {
CircleQueueByArray circleQueueByArray = new CircleQueueByArray(5);
circleQueueByArray.addQueue(12);
circleQueueByArray.addQueue(15);
circleQueueByArray.addQueue(6);
circleQueueByArray.addQueue(7);
System.out.println("---------------------------------------");
//实际只存了4个;
circleQueueByArray.addQueue(8);
System.out.println("实际元素个数->"+circleQueueByArray.getSize());
System.out.println("获取头元素->"+circleQueueByArray.getHead());
//遍历;
circleQueueByArray.toGetAll();
System.out.println("--------------取出一个元素--------------------");
//取出一个元素; 然后查看实际个数与队头;
System.out.println("取出元素--->"+circleQueueByArray.getData());
System.out.println("实际元素个数->"+circleQueueByArray.getSize());
System.out.println("获取头元素->"+circleQueueByArray.getHead());
//遍历
circleQueueByArray.toGetAll();
System.out.println("----------------添加一个元素-------------------");
//添加;
circleQueueByArray.addQueue(8);
//遍历;
circleQueueByArray.toGetAll();
}
---------------------------------------
队列已满,不能入队
实际元素个数->4
获取头元素->12
dataArray[0]=12
dataArray[1]=15
dataArray[2]=6
dataArray[3]=7
--------------取出一个元素--------------------
取出元素--->12
实际元素个数->3
获取头元素->15
dataArray[1]=15
dataArray[2]=6
dataArray[3]=7
----------------添加一个元素-------------------
dataArray[1]=15
dataArray[2]=6
dataArray[3]=7
dataArray[4]=8
以上是关于近期学习数据结构笔记=====>队列的主要内容,如果未能解决你的问题,请参考以下文章