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

队列

思路:使用数组实现

  • 有关队列的描述

1.队头与队尾: 允许元素插入的一端称为队尾,允许元素删除的一端称为队头。
2.入队:队列的插入操作。
3.出队:队列的删除操作。

  • 单向队列

front是队列最前元素(不含),rear是队列最后元素(含)

  • 代码实现
public class Arrayqueue {
	private int front;
	private int rear;
	private int arr[];
	private int Maxsize;
	
	public Arrayqueue() {
		
	}
	public Arrayqueue(int Maxsize) {
	this.Maxsize = Maxsize;
	arr = new int[Maxsize];
	front = -1;//指向队列头前一个数据,数组下标从0开始
	rear = -1;//指向队列尾,即最后一个数据
	}
	public boolean isEmpty() {
		return front == rear;
	}
	public boolean isFull() {
		return rear == Maxsize-1;
	}
	public void addValue(int n) {
		if(isFull()) {
			System.out.println("队列满,无法添加");
			return;
		}
		rear++;//尾指针移动
		arr[rear] = n;
	}
	public int getValue() {
		if(isEmpty()) {
			throw new RuntimeException("队列空,无法获取"); 
		}
		front++;//指针移动
		return arr[front];
	}
	public void showQueue() {
		if(isEmpty()) {
			System.out.println("队列空");
			return;
		}
		//此操作打印了整个数组大小
		for(int i =0;i <arr.length;i++) {
			System.out.printf("arr[%d] = %d\n",i,arr[i]);
		}
	}
	//显示队列的头数据
	public int showhead() {
		if(isEmpty()) {
			throw new RuntimeException("队列空,无法显示头数据");
		}
//		front++;
		return arr[front+1];
	}
}

这里使用front+1而不是front++的原因:
自增和自减对本身的值会进行改变 ,而变量+1或-1 没有对本身的值进行改变。

单向队列的缺点:使用单向队列存储数据并取出后,无法再对原来的位置进行存储。

  • 循环队列

思路:把队列的尾和头接在一起形成一个环,这样当发生假溢出时,尾指针可以跳到数组的开始,重复利用那些已经从队列里删掉的存储单元。
rear是指向队列中最后元素的后一个位置。
重点:
在判断是否为满的时候,预留一个空间,产生假满:

(rear + 1) % Maxsize == front;
//这里使用取模的原因是:front和rear初始化为0,Maxsize为3,当数组长度为3时,我们往其中添加两个元素,所以front=0,rear=2,这时候,我们添加第三个元素是加不了的,将rear=2代入上式得到rear=front,此时就预留一个空间了。

在单向队列中判断是否为满是这样的:

rear = Maxsize - 1;

添加数据时rear的操作:

rear = (rear + 1) % Maxsize;
//rear++;此操作数组有可能越界,这里使用取模使得rear可以回到原来使用过的位置

循环队列中有效数据的个数:

(rear + Maxsize - front) % Maxsize
  • 代码实现
public class CircleArrayqueue {
	// front是队列第一个元素(含),rear是队列倒数第二元素(不含)
	private int front;
	private int rear;
	private int arr[];
	private int Maxsize;

	public CircleArrayqueue() {

	}

	public CircleArrayqueue(int Maxsize) {
		this.Maxsize = Maxsize;
		arr = new int[Maxsize];
//		front = 0;指向队列第一个数据,数组下标从0开始
//		rear = 0;指向队列倒数第二
	}

	public boolean isEmpty() {
		return front == rear;
	}

	// 预留一个空间,产生"假满"
	public boolean isFull() {
		return (rear + 1) % Maxsize == front;
//		rear = Maxsize-1;
	}

	public void addValue(int n) {
		if (isFull()) {
			System.out.println("队列满,无法添加");
			return;
		}
		// 直接将数据加入
		arr[rear] = n;
//		rear++;此操作数组有可能越界
		rear = (rear + 1) % Maxsize;
	}

	public int getValue() {
		if (isEmpty()) {
			throw new RuntimeException("队列空,无法获取");
		}
		// 此时front是指向队列的第一个元素
		// 1.先把front的值保留到一个临时变量
		// 2.将front后移,考虑取模
		// 3.返回临时变量
		int value = arr[front];
		front = (front + 1) % Maxsize;
		return value;
	}

	public void showQueue() {
		if (isEmpty()) {
			System.out.println("队列空");
			return;
		}
		// 从front开始遍历,遍历多少个元素
		for (int i = front; i < front + getSize(); i++) {
			System.out.printf("arr[%d]=%d\n", i % Maxsize, arr[i % Maxsize]);
		}
		//这里输出数组时下标不是从i开始的原因:i有可能超过数组的长度,即越界
		//假设Maxsize=3,front=2,rear=1,front+getSize()=4;根据循环条件,因为预留了一个空间,
		//所以此时数组只有索引为0和2的元素,如果直接输出i,则会越界
	}

	// 求出当前队列有效数据的个数
	public int getSize() {
		return (rear + Maxsize - front) % Maxsize;
	}

	// 显示队列的头数据
	public int showhead() {
		if (isEmpty()) {
			throw new RuntimeException("队列空,无法显示头数据");
		}
//			front++;
		return arr[front];
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值