1.队列的概念:
只允许在一端进行插入数据操作,在另一端进行删除数据操作的线性表,队列具有先进先出FIFO 入队列 :进行插入操作的一端称为队尾.
出队列:进行删除操作的一端称为队头。
图例如下:
2.Queue是一个接口,底层是通过链表实现的
2.队列对应的一些方法:
3.模拟队列的实现:
基于底层为单链表的队列的实现:
1.1:基本结构的构造:
首先,构造节点的类,一个节点通常由数据域,指针域组成,同时创建节点的构造方法,即节点的初始化,具体代码如下:
class Node{
int value; //保存整形的值
Node next; //指向下一个节点的指针
public Node(int value){
this.value = value;
this.next = null;
}
}
栈的结构构造:
一个栈通常包含头节点(front),尾节点(rear),以及当前栈的长度。构造栈的构造方法(将栈初始化),具体代码如下:
class LinkedListQueue{
private Node front; //队头
private Node rear; //队尾
int size;
public LinkedListQueue(){
this.front = null;
this.rear = null;
this.size = 0;
}
1.2‘入队列’方法的实现:
创建一个新节点(newNode)用来储存新的值,判断尾节点(rear)是否为空,不为空,将rear的下一个节点指向新节点 , 之后更新rear尾节点。
当队列中front节点为空时,说明此时队列为空,更新front节点至newNode.
最后成功尾插,将size数量自增1.
具体代码如下:
public void enQueue(int value){
Node newNode = new Node(value);
if(rear!=null) {
rear.next = newNode; //rear的下一个节点指向newNode
}
rear = newNode; //更新rear节点
if(front == null){
front = newNode; //队列为空,更新头节点指针,这样头队列和尾对列都为newNode
}
size++;
}
1.3 出队列方法的实现:
在出队列之前,判断队列是否为空,为空,抛出异常,
不为空,创建一个整形变量value存储队头的值,同时让front节点指向下一个节点,该操作之后如果front == null,说明此时已经到达尾节点,将rear和front都置为空即可,出队列后再将size-1,最后返回整形value的值。
public int deQueue(){
if(front ==null){
throw new RuntimeException("栈为空");
}
int value = front.value;
front = front.next;
if(front == null) //rear和front重合,即只剩一个元素
{
rear = null; //将尾部节点置为空
}
size--; //有效元素数量减1
return value;
}
1.4:获取队列头节点元素(peek)
检查队列是否为空,为空,抛出异常,不为空,返回头节点的值即可。
具体代码如下:
public int peek(){ //获取队头元素
if(front == null){
throw new RuntimeException("栈为空");
}
return front.value; //返回头部元素
在main中运行:
2.以数组为基底的队列的实现:
1.基本结构组成:
指针front(队头指针)、指针rear(队尾指针),capacity(队列的容量),size(队列实际数量)、
以及数组的声明;
构造方法:将以上元素进行初始化,将rear初始化为1。
具体代码如下:
class ArrayQueue{
private int[] queue;
private int front; //头指针
private int rear; //尾指针
private int size; //当前队列大小
private int capacity; //队列容量
public ArrayQueue(int capacity){
//将队列进行初始化
this.capacity = capacity;
this.queue = new int[capacity]; //设置数组容量
this.front = 0;
this.rear = -1;
this.size = 0;
}
2.入队列功能的实现:
在入之前,先判断数组是否已经满,满了的话,抛出异常,
没有满,将rear = (rear+1)%capacity ,将rear移动到下一个位置,
将value赋给当前数组位置即可。
//入队列功能的实现:
public void enqueue(int value){
//判断数组是否已经满
if(capacity == size){
throw new RuntimeException("数组已满");
}
rear = (rear+1)%capacity;//将rear指向下一个地址
queue[rear] = value; //将value赋给rear位置
size++;
}
3.出队列功能的实现:
在出队列之前,判断当前数组是否为空,为空,抛出异常,
不为空,设置一个整形value存储当前front位置的元素,同时将front移动到下一个位置,
同时size--(现有元素数量自减1),最后返回value。
public int dequeue(){ //出栈
if(size ==0){
throw new RuntimeException("空队列");
}
int value = queue[front];
front = (front+1) % capacity;
size--;
return value;
}
4.获取队头元素:
}
public int peek(){
if(size == 0){
throw new RuntimeException("队列为空");
}
return queue[front];
}
5.获取有效元素数量以及判断是否为空:
public int getSize(){
return size;
}
public boolean isEmpty(){
return size ==0; //队列是否为空。
}
今天的分享就到这里,喜欢的老铁来个三联吧!