数据结构和算法(2)-----队列

一、基本介绍

  • 队列是一个有序列表,可以用数组链表来实现
  • 遵循先入先出的原则,即先存入队列的数据,要先取出;后存入队列的数据,要后取出
  • 示意图:

二、数组模拟队列

思路:

  • 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图,其中maxSize是该队列的最大容量。

  • 因为队列的输出,输入是分别从队头和队尾来处理,因此需要两个变量front和rear分别记录队列前后端的下标,front会随着数据输出而改变,而rear则是随着数据输入而改变。
  • 我们将数据存入队列时称为addQueue,addQueue的处理需要有两个步骤,分别是:将尾指针往后移,rear+1;若尾指针rear小于队列的最大下标maxSize-1,则将数据存入rear所指的数组元素中,否则无法存入数据。
  • 队列初始:front和rear均为-1,front指向队头的前一个元素,rear指向队尾元素
  • 队列为空:front==rear
  • 队列为满:rear==maxSize-1

代码实现:

package com.atguigu.queue;

public class ArrayQueue {
	private int maxSize;
	private int front;
	private int rear;
	private int [] arr;
	
	//构造函数,初始化队列
	public ArrayQueue(int maxSize) {
		this.maxSize = maxSize;
		arr=new int [this.maxSize];
		front=-1;
		rear=-1;
	}
	
	
	//判断队列是否为满
	public boolean isFull(){
		if(rear==maxSize-1){
			return true;
		}else{
			return false;
		}
	}
	
	
	//判断队列是否为空
	public boolean isEmpty(){
		if(front==rear){
			return true;
		}else{
			return false;
		}
	}
	
	
	//入队
	public void addQueue(int n){
		if(this.isFull()==false){
			rear++;
			arr[rear]=n;
		}else{
			System.out.println("队列已满");
		}
	}
	
	
	//出队
	public int getQueue(){
		if(this.isEmpty()==false){
			front++;
			return arr[front];
		}else{
			throw new RuntimeException("队列为空");
		}
	}
	
	
	//打印队列内容
	public void showQueue(){
		if(this.isEmpty()){
			System.out.println("队列为空");
		}else{
			System.out.print("[");
			for(int i=front+1;i<=rear;i++){
				if(i!=rear){
					System.out.print(arr[i]+",");
				}else{
					System.out.print(arr[i]);
				}
			}
			System.out.print("]");
			System.out.println();
		}
	}
	
	
	//获取队头元素
	public int headQueue(){
		if(this.isEmpty()==true){
			throw new RuntimeException("队列为空");
		}else{
			return arr[front+1];
		}
	}
}

测试代码:

package com.atguigu.queue;

public class ArrayQueueDemo {
	public static void main(String[] args) {
		ArrayQueue arrayQueue=new ArrayQueue(5);
		
		arrayQueue.showQueue();
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(34);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(45);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(65);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(86);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(93);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(37);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp1=arrayQueue.getQueue();
		System.out.println("取出的元素是:"+temp1);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp2=arrayQueue.getQueue();
		System.out.println("取出的元素是:"+temp2);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp3=arrayQueue.getQueue();
		System.out.println("取出的元素是:"+temp3);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp4=arrayQueue.getQueue();
		System.out.println("取出的元素是:"+temp4);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue.addQueue(100);
		System.out.print("队列的元素:");
		arrayQueue.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue.headQueue());

	}

}

效果图:

问题分析:

  • 目前数组使用一次就不能继续使用了,没有达到复用的效果
  • 将这个数组使用算法,改进成一个环形的队列(取模)

三、数组模拟环形队列

思路:

对前面的数组模拟队列的优化,充分利用数组,因此将数组看做是一个环形的(通过取模的方式来实现)

在环形队列中,如图b所示,队列为满,则front==rear;如图c所示,队列为空时,则front==rear。因此无法判断队列为满或为空,处理方法:少用一个元素空间,约定以“队列头指针在队尾指针的下一位置(值环形的下一个位置)上”作为队满的标志

分析:

  • front变量的含义做一个调整:front指向队列的第一个元素,也就是arr[front]就是队列的第一个元素,front的初始值为0
  • rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,因为希望它空出一个空间作为约定,rear的初始值为0
  • 队列为满:(rear+1)%maxSize==front
  • 队列为空:rear==front
  • 队列中元素的个数(对长):(rear-front+maxSize)%maxSize

代码实现:

package com.atguigu.queue;

public class ArrayQueue1 {
	private int maxSize;
	private int front;
	private int rear;
	private int [] arr;
	
	
	//构造函数,初始化队列
	public ArrayQueue1(int maxSize) {
		this.maxSize = maxSize;
		arr=new int [this.maxSize];
		front=0;
		rear=0;
	}
	
	//判断队列是否已满
	public boolean isFull(){
		if((this.rear+1)%this.maxSize==front){
			return true;
		}else{
			return false;
		}
	}
	
	
	//判断队列是否为空
	public boolean isEmpty(){
		if(this.rear==this.front){
			return true;
		}else{
			return false;
		}
	}
	
	
	//入队
	public void addQueue(int n){
		if(this.isFull()){
			System.out.println("队列已满,不可添加元素");
		}else{
			arr[rear]=n;
			rear=(rear+1)%this.maxSize;    //将rear后移一位,这里必须考虑环形队列(取模)
		}
	}
	
	
	//出队
	public int getQueue(){
		if(this.isEmpty()){
			throw new RuntimeException("队列为空,不可取出元素");
		}else{
			int temp=arr[front];                    //1.先把front对应的值保存到一个临时变量
			front=(front+1)%maxSize;         //2.将front后移一位
			return temp;                                 //3.将临时变量返回
		}
	}
	
	
	
	//获取队列长度
	public int getLength(){
		return (rear-front+maxSize)%maxSize;
	}
	
	
	//打印队列元素
	public void showQueue(){
		if(this.isEmpty()){
			System.out.println("队列为空,无法显示队列");
		}else{
			System.out.print("[");
			for(int i=front;i<(this.getLength()+this.front);i++){
				if(i!=(this.getLength()+this.front-1)){
					System.out.print(arr[i%this.maxSize]+",");
				}else{
					System.out.print(arr[i%this.maxSize]);
				}
			}
			System.out.println("]");
		}
	}
	
	
	//获取队头元素
	public int headQueue(){
		if(this.isEmpty()){
			throw new RuntimeException("队列为空,没有队头元素");
		}else{
			return arr[front];
		}
	}
}
package com.atguigu.queue;

public class ArrayQueueDemo1 {
	public static void main(String[] args) {
		ArrayQueue1 arrayQueue1=new ArrayQueue1(5);
		System.out.println("队列的初始长度:"+arrayQueue1.getLength());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(34);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(78);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(43);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(88);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(22);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp1=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp1);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp2=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp2);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp3=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp3);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp4=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp4);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
//		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(100);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(200);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(300);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(400);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(500);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp5=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp5);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp6=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp6);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp7=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp7);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		int temp8=arrayQueue1.getQueue();
		System.out.println("取出的元素是:"+temp8);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
//		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(1000);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(2000);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(3000);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
		
		System.out.println("-------------------------------------------------");
		arrayQueue1.addQueue(4000);
		System.out.println("队列的当前长度:"+arrayQueue1.getLength());
		System.out.print("队列的元素:");
		arrayQueue1.showQueue();
		System.out.println("队列的队头元素:"+arrayQueue1.headQueue());
	}
}

效果图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值