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

环形队列

思路

  • front指向队列第一个元素初始值为0
  • real指向队列的最后一个元素的后一个位置,因为希望空出空间作为约定,初始值为0
  • (real+1)%MaxSize=front(满)
    牺牲了一个动态空间,并且real指向他,为了使再次为空时real=front
  • real=front(空)
  • 队列中有效的数据个数:(real+MaxSize-frout)%MaxSize

5.jpg

程序



import java.util.Scanner;
public class CircleQueueDemo{
	
	public static void main(String[] args){
		
		//创建队列,大小为3
		ArrayQueue aq=new ArrayQueue(4);
		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出队列\n",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=0;
		real=0;
		
	}
	//判断队列是否为空
	
	public boolean isEmpty(){
		return front==real;
	}
	
	//判断队列是否满了
	
	public boolean isFull(){
		return (real+1)%MaxSize==front;
	}
	
	//插入数据
	public void addQueue(int data){
		if(isFull()){
			System.out.println("队列已满,插入失败");
			return;
		}
		arr[real]=data;
		real=(real+1)%MaxSize;
		System.out.printf("%d入队成功\n",data);
	}
	
	//出队列
	
	public int getQueue(){
		if(isEmpty())
			//throw会自动返回,所以不用return
			throw new RuntimeException("队列为空,无法出队");
			int get1=arr[front];
			front=(front+1)%MaxSize;
		return get1;
	}
	
	//显示队列中所有数据,arr中数据一直都在,即使全都出队列了,
	//因为arr存储的依然是数组的地址。
	//值没有被覆盖掉
	public int valCount(){
		return (real+MaxSize-front)%MaxSize;
	}
	public void showQueue(){
		if(isEmpty()){
			System.out.println("队列为空,没有数据");
			return;
		}		
		for(int i=front;i<front+valCount();i++){
		System.out.printf("arr[%d]=%d\n",i%MaxSize,arr[i%MaxSize]);
		}
		
	}
	//显示头数据,不出队
	public int headQueue(){
		if(isEmpty()){
			//System.out.println("队列为空,没有头数据");
			//return;
			throw new RuntimeException("队列为空,没有头数据");
		}
		return arr[front];
	}
	

	
}


e(exit):退出
s
arr[0]=11
arr[1]=22
arr[2]=33
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
44
队列已满,插入失败
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
11出队列s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[1]=22
arr[2]=33
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
44
44入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[1]=22
arr[2]=33
arr[3]=44
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出

总结:

  • 结束后要关闭输入
  • 数组下标是i%MaxSize,数组值为:arr[i%MaxSize]
  • 留出来的空间是动态的,因此队满,出队后再添加,依然是从队尾加不是从队头或者数组下标为0加
arr[0]=11
arr[1]=22
arr[2]=33
//满状态,空间为4,从0-2

//出队后剩1-2
arr[1]=22
arr[2]=33
arr[3]=44
//再进就是3,1-3满状态,当再出后再进,又从0开始了
g
22出队列
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[2]=33
arr[3]=44
a
请输入要进入队列的数据:
55
55入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[2]=33
arr[3]=44
arr[0]=55
//又回到了0
发布了53 篇原创文章 · 获赞 4 · 访问量 1317

猜你喜欢

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