赞
踩
利用泛型数组作为底层数据结构实现循环队列,定义基本属性和构造方法。
注意:
- //利用泛型数组作为底层数据结构实现循环队列
- private T[] data;
- private static int MAX_SIZE = 11;
- //队头指针
- int front;
- //队尾指针
- int rear;
- //true为满 false为空
- boolean flag = false;
-
- public MyQueue(){
- data = (T[]) new Object[MAX_SIZE];
- front = rear = 0;
- }
- public MyQueue(int maxsize){
- this.MAX_SIZE = maxsize+1;
- data = (T[]) new Object[MAX_SIZE];
- front = rear = 0;
- }
MAX_SIZE为数组实际长度,不是队列实际长度或队列容量
入队(移动队尾指针): rear = ( rear + 1 ) % MAX_SIZE
出队(移动对头指针):front = ( front + 1 ) % MAX_SIZE
判满:front == ( rear + 1 ) % MAX_SIZE
判空:front == rear
为了方便理解,以上是一个容量为4的循环队列的一次循环过程图。可以对着理解一下”队头”和“队尾"两个指针在这个过程中的计算变化。
-
- //入队
- public void enqueue(T t) {
- if(front == (rear+1)%MAX_SIZE || flag){
- throw new RuntimeException("queue is full!!!!!!");
- }else {
- data[rear] = t;
- rear = (rear + 1) % MAX_SIZE;
- if (front == (rear+1)%MAX_SIZE) {
- flag = true;
- }
- }
- }
-
- //出队
- public T dequeue() {
- if(front == rear && !flag){
- throw new RuntimeException("queue is empty!!!!!!");
- }else {
- T element = data[front];
- front = (front + 1) % MAX_SIZE;
- if (front == rear) {
- flag = false;
- }
- return element;
- }
- }
-
- //返回队头元素
- public T peek(){
- if(front == rear && !flag){
- throw new RuntimeException("queue is empty!!!!!!");
- }else {
- return data[front];
- }
- }
-
- //判断队列是否为空
- public boolean isEmpty(){
- return !flag;
- }
-
- //返回队列容量
- public int capacity(){
- return MAX_SIZE-1;
- }
-
-
- //返回队列长度
- public int actualSize(){
- if(rear > front){
- return rear-front;
- } else if (rear < front){
- return MAX_SIZE - (front - rear);
- } else if (rear == front) {
- return 0;
- }
- return -1;
- }
-
- //tostring
- public String toString(){
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("[");
- if(rear > front){
- for (int i = front; i < rear; i++) {
- stringBuilder.append(data[i]);
- if (i != rear - 1){
- stringBuilder.append(",");
- }
- }
- } else if (rear < front){
- for (int i = front; i < MAX_SIZE; i++) {
- stringBuilder.append(data[i]);
- if (i != MAX_SIZE - 1){
- stringBuilder.append(",");
- }
- }
- for (int i = 0; i < rear; i++) {
- stringBuilder.append(data[i]);
- if (i != rear - 1){
- stringBuilder.append(",");
- }
- }
- } else if (rear == front) {
- stringBuilder.append("null");
- }
-
- stringBuilder.append("]");
- return stringBuilder.toString();
- }
思路就是改变MAX_SIZE的值,利用System.arraycopy方法把旧数组复制到新数组。
- public void ensureCapacity(int size) {
- if(size < MAX_SIZE-1){
- throw new RuntimeException("Size is less than MAX_SIZE!!!!!!");
- }else {
- int old = MAX_SIZE;
- MAX_SIZE = size+1;
- T[] oldElements = data;
- data = (T[]) new Object[MAX_SIZE];
- System.arraycopy(oldElements, 0, data, 0, old);
- System.out.println("queue is full, capacity is expanded to " + data.length);
- }
- }
设计一个循环队列,用data[0..MaxSize-1]存放队列元素,用front和rear分别作为队头和队尾指针,另外用一个标志tag标识队列可能空(false)或可能满(true),这样加上front==rear可以作为队空或队满的条件。要求设计队列的相关基本运算算法。
- package queue;
- import org.junit.jupiter.api.BeforeEach;
- import org.junit.jupiter.api.DisplayName;
- import org.junit.jupiter.api.Test;
- public class WorkTwoTest {
- MyQueue<Character> mq;
- @BeforeEach
- @DisplayName("入队测试")
- void init(){
- System.out.println("Test begin.......");
- mq = new MyQueue<>();
- mq.enqueue('a');
- mq.enqueue('b');
- mq.enqueue('c');
- mq.enqueue('d');
- }
-
- @Test
- @DisplayName("出队测试")
- void dequeueTest() {
- System.out.println("出队前:"+mq);
- System.out.println(mq.dequeue()+"已出队!");
- System.out.println("出队后:"+mq);
- System.out.println("========================");
- }
-
- @Test
- @DisplayName("扩容+返回队列长度测试")
- void ensureCapacityTest() {
- System.out.println("队列容量为:" + mq.capacity());
- System.out.println("队列实际长度为:" + mq.actualSize());
- mq.ensureCapacity(20);
- System.out.println("队列容量为:" + mq.capacity());
- System.out.println("========================");
- }
-
- @Test
- @DisplayName("返回队头元素测试")
- void peekTest() {
- System.out.println("队头元素为:"+mq.peek());
- System.out.println("========================");
- }
- }
测试结果如下
根据循环队列的思想,可以学到:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。