java怎么实现环形队列
来源:亿速云
时间:2024-04-01 13:12:38 460浏览 收藏
文章不知道大家是否熟悉?今天我将给大家介绍《java怎么实现环形队列》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!
1、普通队列存在什么问题?
队列大家都知道,有几个重要的属性:
rear:指向队列的尾巴,即最后一个元素所在的位置,初始值为-1
front:指向队列的头部的前一个位置,初始值也为-1
capacity:队列的容量
空队列的rear和front都等于-1,入队时,front不动,rear++,当 rear == capacity - 1
时,队列已满;出队时,rear不动,front++,当front == rear
时,队列为空。看起来很完美,但实际上有问题。假如一个队列capacity = 3
,入队了三个元素,此时front = -1; rear = 2
,然后再将三个元素都出队,此时front = 2, rear = 2
。这时队列明明是空的,但是却不能再入队元素的,因为满足rear = capacity - 1
,也就是相当于这队列是一次性的,用过之后就不能再用了,即使为空也不能再入队了,造成空间的浪费,所以环形队列就出现了。
2、环形队列实现思路:
环形队列中的几个重要属性:
rear:指向队列尾巴的后一个位置,初始值为0
front:指向队列的头部,即第一个元素所在的位置,初始值为0
capacity:队列的容量
下面是环形队列的一些算法:
队列为空时:
front == rear
队列已满时:
(rear + 1) % capacity == front
获取队列元素个数:
(rear + capacity - front) % capacity
入队操作时:
rear = (rear + 1) % capacity
出队操作时:
front = (front + 1) % capacity;
判断队列是否已满是环形队列中最重要也是最难理解的地方。假如有一个队列capacity = 3
,入队操作如下:
第一个元素入队:
front = 0
,因为(rear + 1) % capacity = 1 % 3 != front
,所以元素可以入队,元素入队后rear = 1
;第二个元素入队:
front = 0
,因为(rear + 1) % capacity = 2 % 3 != front
,所以元素可以入队,元素入队后rear = 2
;第三个元素入队:
front = 0
,因为(rear + 1) % capacity = 3 % 3 == front
,所以元素不能入队,队列已满;
队列容量明明是3,只入队了两个元素就告诉我队列满了?没错,这种判断队列是否已满的算法需要牺牲数组的一个空间。
现在进行出队操作:
第一个元素出队:
front = 1
,rear = 2
,(rear + 1) % capacity = 3 % 3 = 0 != front
。
可以发现,当一个元素出队后,又满足入队条件了,所以数组空间就可以重复利用了。
3、代码实操:
public class CircleQueue<E> {
private int capacity;
private int front;
private int rear;
private Object[] arr;
public CircleQueue(int capacity){
this.capacity = capacity;
this.arr = new Object[capacity];
this.front = 0;
this.rear = 0;
}
public boolean isFull(){
return (rear + 1) % capacity == front;
}
public boolean isEmpty(){
return rear == front;
}
public void addQueue(E e){
if (isFull()){
throw new RuntimeException("队列已满,入队失败");
}
arr[rear] = e;
// rear指针后移
rear = (rear + 1) % capacity;
}
public E getQueue(){
if (isEmpty()){
throw new RuntimeException("队列为空,出队失败");
}
E val = (E) arr[front];
front = (front + 1) % capacity;
return val;
}
public int getSize(){
return (rear + capacity - front) % capacity;
}
// 遍历
public void showQueue(){
if (isEmpty()){
return;
}
for (int i = front; i < front + getSize(); i++) {
System.out.printf("arr[%d]=%d\n", i%capacity, arr[i%capacity]);
}
}
public static void main(String[] args){
CircleQueue<Integer> queue = new CircleQueue<>(3);
queue.addQueue(1);
queue.addQueue(2);
queue.showQueue();
//queue.addQueue(3);
System.out.println(queue.getSize());
System.out.println(queue.getQueue());;
queue.addQueue(3);
queue.showQueue();
}
}
今天带大家了解了的相关知识,希望对你有所帮助;关于文章的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
473 收藏
-
383 收藏
-
453 收藏
-
159 收藏
-
351 收藏
-
309 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习