8.队列和栈以及循环队列

1.队列的实现(Java内部的实现和数组实现)

/**
 * 使用 Java 自带的链表(LinkedList)实现的队列。
 * LinkedList 是一个双向链表,支持高效的元素添加和移除。
 */
public static class LinkQueue {
    // 使用 LinkedList 来存储队列中的元素
    public Queue<Integer> queue = new LinkedList<>();

    /**
     * 检查队列是否为空。
     * @return 如果队列为空,返回 true;否则返回 false。
     */
    public boolean isEmpty() {
        return queue.isEmpty();
    }

    /**
     * 向队列尾部添加一个元素。
     * @param x 要添加的元素。
     */
    public void add(int x) {
        queue.offer(x);
    }

    /**
     * 从队列头部移除并返回一个元素。
     * @return 队列头部的元素。
     */
    public int poll() {
        return queue.poll();
    }

    /**
     * 返回队列头部的元素,但不移除它。
     * @return 队列头部的元素。
     */
    Integer peek() {
        return queue.peek();
    }

    /**
     * 返回队列中元素的数量。
     * @return 队列的大小。
     */
    public int size() {
        return queue.size();
    }
}

/**
 * 使用数组实现的队列。
 */
public static class ArrayQueue {
    // 用于存储队列元素的数组
    public int queue[];
    // 队列头部的索引
    public int l;
    // 队列尾部的索引
    public int r;

    /**
     * ArrayQueue 构造函数。
     * @param nums 队列的初始容量。
     */
    public ArrayQueue(int nums) {
        queue = new int[nums];
        l = 0;
        r = 0;
    }

    /**
     * 检查队列是否为空。
     * @return 如果队列为空(l 和 r 相等),返回 true;否则返回 false。
     */
    public boolean isEmpty() {
        return l == r;
    }

    /**
     * 向队列尾部添加一个元素。
     * @param num 要添加的元素。
     */
    public void offer(int num) {
        queue[r++] = num;
    }

    /**
     * 从队列头部移除并返回一个元素。
     * @return 队列头部的元素。
     */
    public int poll() {
        return queue[l++];
    }

    /**
     * 返回队列头部的元素,但不移除它。
     * @return 队列头部的元素。
     */
    int head() {
        return queue[l];
    }

    /**
     * 返回队列尾部的元素,但不移除它。
     * @return 队列尾部的元素。
     */
    public int tail() {
        return queue[r - 1];
    }

    /**
     * 返回队列中元素的数量。
     * @return 队列中元素的数量(r - l)。
     */
    public int size() {
        return r - l;
    }
}

2.栈的实现(Java内部的实现和数组实现)

// 直接用java内部的实现
	// 其实就是动态数组,不过常数时间并不好
	public static class Stack1 {

		public Stack<Integer> stack = new Stack<>();

		// 调用任何方法之前,先调用这个方法来判断栈内是否有东西
		public boolean isEmpty() {
			return stack.isEmpty();
		}

		public void push(int num) {
			stack.push(num);
		}

		public int pop() {
			return stack.pop();
		}

		public int peek() {
			return stack.peek();
		}

		public int size() {
			return stack.size();
		}

	}

	// 实际刷题时更常见的写法,常数时间好
	// 如果可以保证同时在栈里的元素个数不会超过n,那么可以用
	// 也就是发生弹出操作之后,空间可以复用
	// 一般笔试、面试都会有一个明确数据量,所以这是最常用的方式
	public static class Stack2 {

		public int[] stack;
		public int size;

		// 同时在栈里的元素个数不会超过n
		public Stack2(int n) {
			stack = new int[n];
			size = 0;
		}

		// 调用任何方法之前,先调用这个方法来判断栈内是否有东西
		public boolean isEmpty() {
			return size == 0;
		}

		public void push(int num) {
			stack[size++] = num;
		}

		public int pop() {
			return stack[--size];
		}

		public int peek() {
			return stack[size - 1];
		}

		public int size() {
			return size;
		}

	}

3.循环队列

class MyCircularQueue {
    // 存储队列中的元素
    public int[] queue;
    // 队列的左指针(头部),指向队列的第一个元素
    public int l;
    // 队列的右指针(尾部),指向队列的下一个插入位置
    public int r;
    // 队列中元素的数量
    public int size;
    // 队列的最大容量
    public int limit;

    // 构造函数,初始化循环队列的大小为 k
    public MyCircularQueue(int k) {
        queue = new int[k]; // 创建一个长度为 k 的数组用于存储队列元素
        l = r = size = 0; // 初始化左右指针和大小为 0
        limit = k; // 设置队列的最大容量为 k
    }

    // 入队操作,将 value 添加到队列尾部
    public boolean enQueue(int value) {
        if (isFull()) { // 如果队列已满,返回 false
            return false;
        } else {
            queue[r] = value; // 将 value 添加到队列尾部
            r = r == limit - 1 ? 0 : (r + 1); // 更新右指针,如果到达数组末尾则回到 0
            size++; // 队列元素数量加 1
            return true; // 成功添加,返回 true
        }
    }

    // 出队操作,移除队列头部的元素
    public boolean deQueue() {
        if (isEmpty()) { // 如果队列为空,返回 false
            return false;
        } else {
            l = l == limit - 1 ? 0 : (l + 1); // 更新左指针,如果到达数组末尾则回到 0
            size--; // 队列元素数量减 1
            return true; // 成功移除,返回 true
        }
    }

    // 获取队列头部的元素,不移除它,如果队列为空返回 -1
    public int Front() {
        if (isEmpty()) { // 如果队列为空,返回 -1
            return -1;
        } else {
            return queue[l]; // 返回队列头部的元素
        }
    }

    // 获取队列尾部的元素,不移除它,如果队列为空返回 -1
    public int Rear() {
        if (isEmpty()) { // 如果队列为空,返回 -1
            return -1;
        } else {
            int last = r == 0 ? (limit - 1) : (r - 1); // 计算队列尾部元素的索引
            return queue[last]; // 返回队列尾部的元素
        }
    }

    // 检查队列是否为空
    public boolean isEmpty() {
        return size == 0; // 如果元素数量为 0,则队列为空
    }

    // 检查队列是否已满
    public boolean isFull() {
        return size == limit; // 如果元素数量等于队列的最大容量,则队列已满
    }
}

4.对应题目

题目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值