队列的顺序存储实现
基本概念
队是一种线性结构,是一种只允许在表的一端进行插入操作,而另外一端进行删除的线性表。
- 允许插入的一端称之为“队尾”:插入又称之为入队
- 允许删除的一端称之为“队头”:删除又称之为出队
队列的顺序存储实现
/**
* 队列的顺序存储实现
* * 队是一种线性结构,是一种只允许在表的一端进行插入操作,而另外一端进行删除的线性表
* * 允许插入的一端称之为“队尾”:插入又称之为入队
* * 允许删除的一端称之为“队头”:删除又称之为出队
*
* 约定:队头指针 this.front 指向队头元素所在位置的前一个位置,而队尾指针 this.rear 指向队尾元素所在位置
*
*/
public class QueueList {
public int size;
public int front;
public int rear;
public int[] queue;
/**
* 初始化队列
*/
public QueueList(int size) {
this.size = size;
this.front= -1;
this.rear = -1;
this.queue= new int[this.size];
}
/*
* 判空
* 若队头指针和队尾指针相等,则队列为空
*/
public boolean isEmpty() {
return this.front==this.rear;
}
/**
* 判满
* 若队尾指针rear指向最后一个位置,即size-1,则队列已满
*
*/
public boolean isFull() {
return this.rear+1==this.size;
}
/**
* 获取队头元素
* 判空
* 其次,front指向队头元素的前一个位置,因此返回front+1的元素
*/
public Integer getFrontEle() {
if(isEmpty())return -1;
return this.queue[this.front+1];
}
/**
* 获取队尾元素
* 判空,而后直接返回
*/
public Integer getRearEle() {
if(isEmpty())return -1;
return this.queue[this.rear];
}
/**
* 入队操作
* 判满,而后rear指针+1,将元素放入rear位置
*/
public boolean InQueue(int value) {
if(isEmpty())return false;
this.queue[++this.rear]=value;
return true;
}
/**
* 出队操作
* 判空,而后front+1,并将其中元数返回
*/
public Integer OutQueue() {
if(isEmpty())return -1;
return this.queue[++this.front];
}
}
存在的问题:
* 这里存在的一个很大的问题是:
* 数组中,队头指针front走过的位置不会再被使用,这就造成的存储上的浪费
* 相应的提出了循环队列的实现。
* 值得一提的是,对列的链式存储不会考虑存储浪费问题,
* 因为,结点占用的空间在动态的创建和释放过程中。
循环队列
/**
* 约定:
* self.size 为循环队列的最大元素个数。
* 队头指针 self.front 指向队头元素所在位置的前一个位置,
* 而队尾指针 self.rear 指向队尾元素所在位置
*/
public class CycleQueueList {
public static void main(String[] args) {
CycleQueueList queu = new CycleQueueList(3);
System.out.println(queu.InQueue(1));
System.out.println(queu.InQueue(2));
System.out.println(queu.InQueue(3));
System.out.println(queu.InQueue(4));
System.out.println(queu.getRearEle());
System.out.println(queu.isFull());
System.out.println(queu.OutQueue());
System.out.println(queu.InQueue(4));
System.out.println(queu.getRearEle());
}
public int size;
public int front;
public int rear;
public int[] queue;
/**
* 初始化队列
*/
public CycleQueueList(int size) {
this.size = size+1;// +1的目的在于,front指向了头元素的前一个结点,因而浪费了一个存储空间,因此+1补充
this.front= 0;
this.rear = 0;
this.queue= new int[this.size];
}
/**
* 判断队列是否为空
* 当front与rear指向同一个位置时,队列为空
*/
public boolean isEmpty() {
return this.front == this.rear;
}
/**
* 判断队列是否已满
* front在rear的下一个位置,则判断为满
* 注意:这与普通队列的判满不同,普通队列是将rear与size进行比较,
* 同时,判满常用于入队操作中,因此移动的总是rear指针
*/
public boolean isFull() {
return (this.rear+1)%this.size == this.front;
}
/**
* 获取队头元素
* 判空
* 如果不为空,因为 front 指向队头元素所在位置的前一个位置,所以队头元素在 front 后一个位置上
*/
public Integer getFrontEle() {
if(isEmpty())return -1;
return this.queue[(this.front+1)%this.size];
}
/**
* 获取队尾元素
* 判空,
* 如果不为空,则直接返回rear指向的元素
*/
public Integer getRearEle() {
if(isEmpty())return -1;
return this.queue[this.rear];
}
/**
* 入队操作
* 队尾入队
* 判满,
* 如果未满,将元素放入(rear+1)%size位置
*/
public boolean InQueue(int val) {
if(isFull())return false;
this.rear = (this.rear+1)%this.size;
this.queue[this.rear]=val;
return true;
}
/**
* 出队操作
* 队头出队
* 判空,
* 如果未空,将front=(front+1)%size,并将其指向的元素返回
*/
public boolean OutQueue() {
if(isEmpty())return false;
this.front = (this.front+1)%this.size;
return true;
}
}