队列定义
队列就是一个先入先出的数据结构,用数组可以实现定长队列;
实现方式
这是第一种完整的实现思路,无需头指针,默认数组下标未0的元素是头指针。当队列未满时,队列尾指针后移一位,尾指针所指向的元素被赋予插入的值。当队列不为空时,将队列的第一个元素移除,除第一元素外后续元素向前移一位。这种remove方法比较直观但是开销会比较大,涉及到元素的整体移动。
class ArrayQueue{
private int maxSize; //队列最大size
private int end; //队列尾指针
private int[] array; //队列数组
public ArrayQueue(int maxSize){
this.maxSize = maxSize;
array = new int[maxSize];
end = -1;
printQueue();
}
//队列是否为控
public boolean isEmpty(){
return end == -1;
}
//队列是否满
public boolean isFull(){
return end==(maxSize-1);
}
//队列添加元素
public void add(int n){
if(isFull()){
System.out.println("队列已满,不能添加");
return;
}
end++;
array[end] = n;
printQueue();
}
//队列移除元素
public void remove (){
if(isEmpty()){
throw new RuntimeException("队列为空,不可移除");
}
for(int i=0;i<array.length-1;i++){
array[i]=array[i+1];
}
array[array.length-1] = 0;
end--;
printQueue();
}
//遍历输出队列
public void printQueue(){
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
}
}
对于上面remove方法的优化。使用队列头指针,remove元素将头指针后移一位。与上面的实现思路比较队列的元素移除,开销更小。
class ArrayQueue{
private int maxSize; //队列最大size
private int front; //队列头指针,指向第一个元素前一个位置
private int rear; //队列尾指针,指向最后一个元素
private int[] array; //队列数组
public ArrayQueue(int maxSize){
this.maxSize = maxSize;
array = new int[maxSize];
front =-1;
rear = -1;
printQueue();
}
//队列是否为空
public boolean isEmpty(){
return rear == front;
}
//队列是否满
public boolean isFull(){
return rear==(maxSize-1);
}
//队列添加元素
public void add(int n){
if(isFull()){
System.out.println("队列已满,不能添加");
return;
}
rear++;
array[rear] = n;
printQueue();
}
public void remove(){
if(isEmpty()){
throw new RuntimeException("队列为空,不可移除");
}
front++;
printQueue();
}
//遍历输出队列
public void printQueue(){
if(isEmpty()){
System.out.println("队列为空");
}else{
for(int i=front+1;i<=rear;i++){
System.out.print(array[i]+" ");
}
System.out.println();
}
}
}
第二种方式其实还有缺陷,数组有限的空间得不到利用,经过几次add ,remove操作后,front指针前面部分的空间无法得到有效的利用。这时候就可以用环形队列来实现了。
//环形队列的实现
class ArrayQueue{
private int maxSize; //队列最大size
private int front; //队列头指针,指向第一个元素
private int rear; //队列尾指针,指向最后一个元素后一个位置
private int[] array; //队列数组
public ArrayQueue(int maxSize){
this.maxSize = maxSize;
array = new int[maxSize];
front =0;
rear = 0;
printQueue();
}
//队列是否为空
public boolean isEmpty(){
return rear == front;
}
//队列是否满
public boolean isFull(){
//System.out.println(rear);
return (rear+1)%(maxSize+1)==front;
}
//队列添加元素
public void add(int n){
if(isFull()){
System.out.println("队列已满,不能添加");
return;
}
rear++;
array[(rear-1)%maxSize] = n;
printQueue();
}
public void remove(){
if(isEmpty()){
throw new RuntimeException("队列为空,不可移除");
}
front++;
printQueue();
}
//遍历输出队列
public void printQueue(){
if(isEmpty()){
System.out.println("队列为空");
}else{
for(int i=front;i<rear;i++){
System.out.print(array[i%maxSize]+" ");
}
System.out.println();
}
}
}
思考
首先这里所谓的指针和C语言里面的指针的含义有些相似实则不同,C语言里的指针是指向内存地址的,我们这里的指针更像是数组下标。这里的front和rear在队列里有着很关键的作用。