Java数据结构与算法----队列

队列

  • 队列是一个有序列表,可以使用数组或者链表实现
  • 遵循先入先出的原则。 即先存入列表的数据要先取出,后存入的要后取出。

采用数组模拟队列

思路分析

4.png

  • front指向队列的头部的前一个位置,初始为-1
  • rear指向队列的尾部(尾部这个位置)。初始为-1
  • 当有数据输入时,front不动,real向上移,当rear = maxSize - 1 时,队列满,无法再加入数据;
  • 当有数据 输出时,队列的尾部不动,头部上移,rear = front 时,队列空,此时无数据可以取出
  • 先进先出

代码


import java.util.Scanner;
public class ArrayQueueDemo{
	
	public static void main(String[] args){
		
		//创建队列,大小为3
		ArrayQueue aq=new ArrayQueue(2);
		Scanner ss=new Scanner(System.in);
		//用来接收输入的字符
		char c=' ';
		boolean loop=true;
		while(loop){
			
		//界面
		System.out.println("s(showQueue):显示队列");
		System.out.println("a(addQueue):插入队列");
		System.out.println("g(getQueue):出队列");
		System.out.println("h(headQueue):显示队列的头");
		System.out.println("e(exit):退出");
		//取第0位的字符
		c=ss.next().charAt(0);
		switch(c){
			case 's':
			aq.showQueue();
				break;
			case 'a':
		
				System.out.println("请输入要进入队列的数据:");
				int data=ss.nextInt();
				aq.addQueue(data);
				
				break;
			
			case 'g':
				try{
					int data2=aq.getQueue();
					System.out.printf("%d出队列",data2);
				
				}catch(Exception e){
					System.out.println(e.getMessage());
				}
				break;
			case 'h':
				try{
					int data3=aq.headQueue();
					System.out.printf("%d是现在队列的队头\n",data3);
				}catch(Exception e){
					System.out.println(e.getMessage());
				}
				break;
			case 'e':
				loop=false;
			    //关闭输入
			    ss.close();	   
			    System.out.println("退出……");
				break;
			default:
				break;
			
			
		}
		}
		
		
	}
}

class ArrayQueue{
	private int MaxSize;
	private int[] arr;
	private int front;
	private int real;
	
	//构造方法
	ArrayQueue(int maxsize){
		//创建队列
		MaxSize=maxsize;
		arr=new int[MaxSize];
		front=-1;
		real=-1;
		
	}
	//判断队列是否为空
	
	public boolean isEmpty(){
		return front==real;
	}
	
	//判断队列是否满了
	
	public boolean isFull(){
		return real==MaxSize-1;
	}
	
	//插入数据
	public void addQueue(int data){
		if(isFull()){
			System.out.println("队列已满,插入失败");
			return;
		}
		arr[++real]=data;
		System.out.printf("%d入队成功\n",data);
	}
	
	//出队列
	
	public int getQueue(){
		if(isEmpty())
			//throw会自动返回,所以不用return
			throw new RuntimeException("队列为空,无法出队");
		front++;
		return arr[front];
	}
	
	//显示队列中所有数据,arr中数据一直都在
	//因为arr存储的依然是数组的地址
	//值没有被覆盖掉
	
	public void showQueue(){
		if(isEmpty()){
			System.out.println("队列为空,没有数据");
			return;
		}
			
		for(int i=0;i<MaxSize;i++){
		System.out.printf("arr[%d]=%d\n",i,arr[i]);
		}
		
	}
	//显示头数据,不出队
	public int headQueue(){
		if(isEmpty()){
			//System.out.println("队列为空,没有头数据");
			//return;
			throw new RuntimeException("队列为空,没有头数据");
		}
		return arr[front+1];
	}
	
	
	
}
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
队列为空,没有数据
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
11
11入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
22
22入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
33
队列已满,插入失败
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
11出队列s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
22出队列s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
队列为空,无法出队
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
44
队列已满,插入失败
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
e
退出……

问题及优化

  • 结束后要关闭输入

  • 数组不能重复用,即使空也不能再入队,队列不能循环使用,没有达到复用效果

  • 使用算法改进成环形队列:取模

注意:
数组为空,只是逻辑上判断为空,内存里还是满的

发布了53 篇原创文章 · 获赞 4 · 访问量 1317

猜你喜欢

转载自blog.csdn.net/weixin_43351473/article/details/104696966