欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

队列详解

程序员文章站 2022-06-06 20:37:48
...

队列详解

队列定义

在这里插入代码片队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

创建队列

创建初始数组 int arr[maxSize] 定义头指针 front = -1,尾指针 rear = -1.
队列详解

队列的基本操作

添加元素

  1. 判断队列是否为满队列,若为满队列则输出提示信息,否则执行2;
  2. rear ++ ;
  3. arr[rear] = temp;
  4. 队列添加元素成功;
    队列详解

取出元素

  1. 判断队列是否为空,若为空输出错误提示信息,否则执行2
  2. front ++;
  3. 队列元素成功取出;

判断队列是否为空

  1. 若front == rear 则队列为空,否则队列不为空

判断队列是否为满

  1. 若 rear == maxSize 则队列为满,否则队列不是满队列
    查看当前元素且不取出
  2. 判断队列是否为空,若为空输出错误提示信息,否则执行2
  3. Return arr[front+1];

问题分析优化

  1. 此方法实现的队列只能使用一次,且空间利用率不高。
  2. 可以考虑使用环形队列

环形队列

特点

它是一个首尾相连的FIFO的数据结构,采用数组的线性空间,数据组织简单。能很快知道队列是否满为空。能以很快速度的来存取数据。
因为有简单高效的原因,甚至在硬件都实现了环形队列.

应用

环形队列广泛用于网络数据收发,和不同程序间数据交换(比如内核与应用程序大量交换数据,从硬件接收大量数据)均使用了环形队列.

环形队列的实现

实现环形队列最重要的一个问题就是队空和队满的判断问题,在上面的队列实现方法中判定队满条件为 front == rear。判定队空条件为 rear == maxsize

  1. 考虑如何实现数组的循回,假设现在rear== maxSize 那么如何可以使rear指向arr[0]。我们发现(rear++)% maxSize 可以实现数组的循环。

  2. 考虑如可判断队满和队空。若不浪费数组空间 则可能出现一下俩种情况:

  3. 所以我们可以消耗一个数组空间

则队满状态的判断条件为(rear++)% maxSize == front。队空状态的判断条件为 front == rear。
队列详解队列详解
队列详解

环形队列基本操作

创建环形队列

创建初始数组 int arr[] 头指针 front = 0,尾指针 rear = 0(注意必须设置为0,否则判断队空,队满会失败),设置数组容量maxSize。

class CircleArray
{
	private int front ;
	private int rear  ;
	private int [] arr;
	private int maxSize;

	public CircleArray(int maxSize) {
		this.arr = new int [maxSize] ;
		this.maxSize = maxSize;
	}
}

判断是否为空队列

  1. 判定front==rear是否为真,若为真则队空,否则该队列不为空。
public boolean isEmpty(){
		return this.front == this.rear;
	}

判断是否为满队列

  1. 判断(rear+1)% maxSize == front 是否为真,若为真则队满,否则该队列不是满队列。
public boolean isFull(){
		return (this.rear+1) % this.maxSize == this.front;
}

添加元素

  1. 判断是否队满,若队满则输出错误提示信息。否则执行2.
  2. Rear = (rear+1)%maxSize
  3. Arr[rear] = temp;
  4. 添加元素成功;
	public void addQueue(int temp){
		if(this.isFull()){
			System.out.println("队列满,不能添加数据");
			return;
		}
		this.rear = (this.rear+1) % this.maxSize;
		this.arr[this.rear] = temp;
	}

取出数据

  1. 判断是否队空,若队空则输出错误提示信息。否则执行2.
  2. Front = (front+1)%maxSize;
  3. 取出数据成功;
	public int  getQueue(){
		if(this.isEmpty()){
			throw new RuntimeException("队列空,不能取数据");
		}
		this.front = (this.front+1) % this.maxSize;
		int value = this.arr[this.front];
		return value;
	}

查看当前元素且不取出

  1. 判断是否队空,若队空则输出错误提示信息。否则执行2.
  2. Return arr[front+1]
	public int headQueue(){
		if(this.isEmpty()){
			throw new RuntimeException("队列空,无数据");
		}
		return this.arr[(this.front+1) % this.maxSize];
	}

完整代码

import java.util.Scanner;

class CircleArrayQueueDemo 
{
	public static void main(String[] args) 
	{
		 CircleArray queue = new CircleArray(4);
		 char key = ' ';
		 Scanner scanner = new Scanner(System.in);
		 boolean lop = true;
		 while (lop)
		 {
			 System.out.println("e: 退出程序");
			 System.out.println("a: 添加数据");
			 System.out.println("g: 取出数据");
			 System.out.println("h: 查看队列头数据");
			 key = scanner.next().charAt(0);
			 switch (key)
			 {
			 case 'a':
				 System.out.println("输入一个数字");
			 	int value = scanner.nextInt();
				queue.addQueue(value);
				break;
			case 'g':
				try{
					int res = queue.getQueue();
					System.out.printf("取出的数据是%d\n",res);
				}
				catch(Exception e){
					System.out.println(e.getMessage());
				}
				break;
			case 'h':
				try{
					int res = queue.headQueue();
					System.out.printf("取出的数据是%d\n",res);
				}
				catch(Exception e){
					System.out.println(e.getMessage());
				}
				break;
			case 'e':
				scanner.close();
				lop=false;
				break;

			 }
		 }
		 System.out.println("程序退出");
	}
}
class CircleArray
{
	private int front ;
	private int rear  ;
	private int [] arr;
	private int maxSize;

	public CircleArray(int maxSize) {
		this.arr = new int [maxSize] ;
		this.maxSize = maxSize;
		
	}
	public boolean isEmpty(){
		return this.front == this.rear;
	}
	public boolean isFull(){
		return (this.rear+1) % this.maxSize == this.front;
	}
	public void addQueue(int temp){
		if(this.isFull()){
			System.out.println("队列满,不能添加数据");
			return;
		}
		this.rear = (this.rear+1) % this.maxSize;
		this.arr[this.rear] = temp;
	}
	public int  getQueue(){
		if(this.isEmpty()){
			throw new RuntimeException("队列空,不能取数据");
		}
		this.front = (this.front+1) % this.maxSize;
		int value = this.arr[this.front];
		return value;
	}
	public int headQueue(){
		if(this.isEmpty()){
			throw new RuntimeException("队列空,无数据");
		}
		return this.arr[(this.front+1) % this.maxSize];
	}

}

每日一言:

玫瑰花:"我并非如此的弱不禁风...夜晚的凉风对我倒有好处。我是一朵花啊。"
																———  小王子