队列-java数据结构

Posted 旧时星空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了队列-java数据结构相关的知识,希望对你有一定的参考价值。

队列

(1)用数组模拟队列(非环形)

该模拟队列为一次性队列,即填充数据后取出,则front依次后退会等于rea即头与尾相同而队列空间为0。

队列先进先出,后进后出,在增加数据时头固定不动而尾会逐渐增加,在取出数据时尾固定则头依次后移。


public class ArrayQueueDemo {
      public static void main(String[] args) {
    	  ArrayQueue queue=new ArrayQueue(3);
    	  boolean loop=true;
    	  char k=' ';
    	  Scanner scan=new Scanner(System.in);
    	  while(loop) {
    		  System.out.println("a:add");
    		  System.out.println("g:get");
    		  System.out.println("s:show");
    		  System.out.println("h:showHead");
    		  System.out.println("e:exit");
    		  //String key=scan.next();
    		 k=scan.next().charAt(0);
    		 System.out.println(k);
    		  switch(k) {
    		  case 'a':
    			  System.out.println("请输入操作的数据");
    			  int a=scan.nextInt();
    			  queue.addQueue(a);
    			  //System.out.println("操作成功");
    			  break;
    		  case 'g':
    			  try {
    				  int b=queue.getQueue();
    				  System.out.println(b);
    			  }catch(Exception e) {
    				  System.out.println(e.getMessage());
    			  }
    			  //System.out.println("操作成功");
    			  break;
    		  case 's':
    			  try {
    			  queue.showQueue();
    			  }catch(Exception e) {
    				  System.out.println(e.getMessage());
    			  }
    			  //System.out.println("操作成功");
    			  break;
    		  case 'h':
    			  try {
        			  int b=queue.headQueue();
        			  System.out.println(b);
        			  }catch(Exception e) {
        				  System.out.println(e.getMessage());
        			  }
    			  //System.out.println("操作成功");
        			  break;
    		  case 'e':
    			  scan.close();
    			  loop=false;
    			  //System.out.println("操作成功");
    			  break;
    		  }	  
    	  }
    	  System.out.println("推出程序");
      }
}

class ArrayQueue{
	private int maxSize;
	private int front;
	private int rear;
	private int[] arr;
	//创建一个最大容量的数组模拟队列
	public ArrayQueue(int arrmaxSize) {
		maxSize=arrmaxSize;
		arr=new int[maxSize];
		front=-1;//队列头位于数组之前,即不在队列数据中
		rear=-1;//队列尾包含在数组中
	}
	//判断队列是否为空
	public boolean isEmpty() {
		return front==rear;
	}
	//判断是否为满
	public boolean isFull() {
		return (rear==maxSize-1);
	}
	//增加数据
	public void addQueue(int a) {
		//判断是否为满
		if(isFull()) {
			System.out.println("已满");
			return;
		}
		rear++;
		arr[rear]=a;
	}
	//取出队列
	public int getQueue() {
		//判断是否为空
		if(isEmpty()) {
			throw new RuntimeException("为空无法取出数据");
		}
		front++;
		return arr[front];
	}
	//显示全部数据
	public void showQueue() {
		if(isEmpty()) {
			throw new RuntimeException("为空,无数据");
		}
		for(int i=0;i<arr.length;i++) {
			System.out.printf("arr[%d]=%d\\n",i, arr[i]);
		}
	}
	//显示队列头
	public int headQueue() {
		if(isEmpty()) {
			throw new RuntimeException("队列为空");
		}
		return arr[front+1];
	}
}
g
g
为空无法取出数据//已为空
a:add
g:get
s:show
h:showHead
e:exit
a
a
请输入操作的数据
12
已满    //数组空间为0
a:add
g:get
s:show
h:showHead
e:exit

e
e
退出程序

环形队列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XnQOcvw3-1632554385380)(E:\\学习笔记\\java数据结构与算法\\截图\\屏幕截图 2021-09-19 203637.png)]

思路2中空出一个空间作为约定是rear在空余空间代表循环队列已满。

环形队列的实现最重要在于下标的取模,第一次front=0,rear=0,设置maxSize=4,即除去空的一个空间存储数据的空间为3。

依次加入三个数据(a[0]:11,a[1]:12,a[2]:13)之后,front=0,rear=3;此时根据条件也知道空间已满,

(1)取出队列第一个数据,即取出11后,front=1(下标),知空间空余一个,加入数据,此时rear将实现循环,rear=(rear+1)%maxSize=0

(2)在不可循环中当队列中的数据全部取出时,便不可再加入数据,同样全部取出数据,front=rear=3,空间为空,rear=(rear+1)%maxSize则再次加入的数据可存储在下标3中,而此时的有效数据为**(rear+maxSize-front)%maxSize**=1,个人认为在求有效数据个数时加上maxSize再减去front是为了使得结果不为负数

​ (1)rear>front,则结果自然为正

​ (2)rear<front,则**(rear+maxSize-front)%maxSize**=(front-rear+maxSize)%maxSize,举例子front=3,rear=0;maxSize=4时。

class CircleQueue{
	private int maxSize;
	private int front;
	private int rear;
	private int[] arr;
}

基本属性,下面是各类操作

//创建可循环使用的队列数组,rear和front都设置为0
	public CircleQueue(int arrmaxSize) {
		maxSize=arrmaxSize;
		arr=new int[maxSize];
		//front=0;//队列头位于数组第一个数据的位置
		//rear=0;//创建一个maxSize的数组实际上留出最后一个位置用于完成循环队列
	}
	//判断队列是否为空
		public boolean isEmpty() {
			return front==rear;
		}
	//判断是否为满
		public boolean isFull() {
			return (rear+1)%maxSize==front;
		}
	//得到队列的有效数据个数
		public int data() {
			return(rear+maxSize-front)%maxSize;
		}
	//增加数据
		public void addQueue(int a) {
			//判断是否为满
			if(isFull()) {
				System.out.println("已满");
				return;
			}
			arr[rear]=a;//加入数据
			rear=(rear+1)%maxSize;//rear后移,考虑循环要取模
		}
	//取出队列
		public int getQueue() {
			//判断是否为空
			if(isEmpty()) {
				throw new RuntimeException("为空无法取出数据");
			}
			int a=0;
			a=arr[front];
			front=(front+1)%maxSize;
			return a;
		}
		//显示全部数据
		public void showQueue() {
			if(isEmpty()) {
				throw new RuntimeException("为空,无数据");
			}
			   for(int i=front;i< front+data();i++) {
				   System.out.printf("arr[%d]=%d\\n", i%maxSize,arr[i%maxSize]);
			}//i取模实现下标的循环
		}
		public int headQueue() {
			if(isEmpty()) {
				throw new RuntimeException("为空无法取出数据");
			}
			return arr[front];
		}
		//显示rear的下标
		public int Rear() {
			return rear;
		}
		//显示front
		public int Front() {
			return front;
		}
}

如下是测试代码

public class CircleQueueDemo {

	public static void main(String[] args) {
		 CircleQueue queue=new CircleQueue(4);
   	  boolean loop=true;
   	  char k=' ';
   	  Scanner scan=new Scanner(System.in);
   	  while(loop) {
   		  System.out.println("a:add");
   		  System.out.println("g:get");
   		  System.out.println("s:show");
   		  System.out.println("h:showHead");
   		  System.out.println("e:exit");
   		  //String key=scan.next();
   		 k=scan.next().charAt(0);
   		 //System.out.println(k);
   		  switch(k) {
   		  case 'a':
   			  System.out.println("请输入操作的数据");
   			  int a=scan.nextInt();
   			  queue.addQueue(a);
   			  //System.out.println("操作成功");
   			  break;
   		  case 'g':
   			  try {
   				  int b=queue.getQueue();
   				  System.out.println(b);
   			  }catch(Exception e) {
   				  System.out.println(e.getMessage());
   			  }
   			  //System.out.println("操作成功");
   			  break;
   		  case 's':
   			  try {
   			  queue.showQueue();
   			  }catch(Exception e) {
   				  System.out.println(e.getMessage());
   			  }
   			  //System.out.println("操作成功");
   			  break;
   		  case 'h':
   			  try {
       			  int b=queue.headQueue();
       			  System.out.println(b);
       			  }catch(Exception e) {
       				  System.out.println(e.getMessage());
       			  }
   			  //System.out.println("操作成功");
       			  break;
   		  case 'e':
   			  scan.close();
   			  loop=false;
   			  //System.out.println("操作成功");
   			  break;
   		  case'r':
   			  int r=0;
   			  int f=0;
   			  int x=0;
   			  r=queue.Rear();
  			  f=queue.Front();
  			  x=(r+queue.maxSize-f)%queue.maxSize;
  			  System.out.println("f:"+f);
   			  System.out.println("r:"+r);
   			  System.out.println("maxSize:"+queue.maxSize);
   			  System.out.println("有效数据个数:"+x);
   		  }	  
   	  }
   	  System.out.println("推出程序");
     }
	}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBV7kr6n-1632554385382)(C:\\Users\\red wind\\AppData\\Roaming\\Typora\\typora-user-images\\image-20210920230811193.png)]
=(r+queue.maxSize-f)%queue.maxSize;
System.out.println(“f:”+f);
System.out.println(“r:”+r);
System.out.println(“maxSize:”+queue.maxSize);
System.out.println(“有效数据个数:”+x);
}
}
System.out.println(“推出程序”);
}
}


[外链图片转存中...(img-yBV7kr6n-1632554385382)]

以上是关于队列-java数据结构的主要内容,如果未能解决你的问题,请参考以下文章

perl中的队列

Java实现队列结构的详细代码

如何在片段中使用 GetJsonFromUrlTask​​.java

java数据结构与算法:单向队列与环形队列详解(图片+代码)

数据结构队列及其Java代码实现

数据结构 Java数据结构 栈和队列 以及LeetCode相关面试题