当前位置: 首页 > news >正文

【数据结构】——队列,栈(基于链表或数组实现)

目录

一.队列

1.基于环形数组实现

两个指针—>需要多一个空位 即定义时,容量+1

2.基于单向环形链表实现(带哨兵)

3.双栈模拟队列

4.双端队列

1.双向链表实现

2.循环数组实现

3.阻塞队列(双锁实现)

二.栈(可以记住来时的路)

1.单向链表实现

2.数组实现

3.力扣20题(有效括号)


一.队列

1.基于环形数组实现

数组实现时,要主要数组下标越界的问题,指针在移动时,用取模的方式移动

两个指针—>需要多一个空位 即定义时,容量+1

public class ArrayQueue4<E> implements Queue<E>, Iterable<E> {static class Node<E>{E value;Node<E> next;public Node(E value, Node<E> next) {this.value = value;this.next = next;}}private E[] array;private int head;private int tail;@SuppressWarnings("all")public ArrayQueue4(int capacity) {this.array = (E[]) new Object[capacity + 1];}@Overridepublic boolean offer(E value) {//判满if (isFull()){return false;}//先赋值再++array[tail] = value;//++要避免越界tail = (tail + 1) % array.length;return true;}@Overridepublic E poll() {//判空if (isEmpty()){return null;}//先赋值再++E e = array[head];//++要避免越界head = (head + 1) % array.length;return e;}@Overridepublic E peek() {//判空if (isEmpty()){return null;}E e = array[head];return e;}@Overridepublic boolean isEmpty() {return head == tail;}@Overridepublic boolean isFull() {return head == (tail + 1) % array.length;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = head;@Overridepublic boolean hasNext() {return p != tail;}@Overridepublic E next() {E e = array[p];p = (p + 1) % array.length;return e;}};}
}

2.基于单向环形链表实现(带哨兵)

以head作为哨兵节点。

public class LinkedListQueue1<E> implements Queue<E>, Iterable<E>  {private static class Node<E> {E value;Node<E> next;public Node(E value, Node<E> next) {this.value = value;this.next = next;}}private Node<E> head = new Node<>(null, null);private Node<E> tail;private int size;private int capacity = Integer.MAX_VALUE;{this.tail = head;}public LinkedListQueue1(int capacity) {this.capacity = capacity;}public LinkedListQueue1() {}@Overridepublic boolean offer(E value) {if (isFull()){return false;}Node added = new Node<E>(value, head);tail.next = added;tail = added;size++;return true;}@Overridepublic E poll() {if (isEmpty()){return null;}Node removed = head.next;head.next = removed.next;size--;return (E) removed.value;}@Overridepublic E peek() {if (isEmpty()){return null;}Node removed = head.next;return (E) removed.value;}@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic boolean isFull() {return size == capacity;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = head.next;@Overridepublic boolean hasNext() {return p != head;}@Overridepublic E next() {Node temp = p;p = p.next;return (E) temp.value;}};}
}

3.双栈模拟队列

4.双端队列

1.双向链表实现

不同于单向链表,双向链表只需要一个哨兵阶段即可,不用head,tail节点

public class LinkedListDeque1<E> implements Deque<E>, Iterable<E>{private static class Node<E>{Node<E> prev;E value;Node<E> next;public Node(Node<E> prev, E value, Node<E> next) {this.prev = prev;this.value = value;this.next = next;}}private Node<E> s = new Node<>(null, null, null);private int size;private int capacity;public LinkedListDeque1(int capacity) {this.capacity = capacity;s.next = s;s.prev = s;}public LinkedListDeque1() {}@Overridepublic boolean offerFirst(E e) {if (isFull()){return false;}Node a = s;Node b = s.next;Node<E> addFirst = new Node<>(a, e, b);a.next = addFirst;b.prev = addFirst;size++;return true;}@Overridepublic boolean offerLast(E e) {if (isFull()){return false;}Node a = s.prev;Node b = s;Node<E> addLast = new Node<>(a, e, b);a.next = addLast;s.prev = addLast;size++;return true;}@Overridepublic E pollFirst() {if (isEmpty()){return null;}Node<E> removeFirst = s.next;s.next = removeFirst.next;removeFirst.next.prev = s;size--;return removeFirst.value;}@Overridepublic E pollLast() {if (isEmpty()){return null;}Node<E> removeLast = s.prev;s.prev = removeLast.prev;removeLast.prev.next = s;size--;return removeLast.value;}@Overridepublic E peekFirst() {if (isEmpty()){return null;}Node<E> removeFirst = s.next;return removeFirst.value;}@Overridepublic E peekLast() {if (isEmpty()){return null;}Node<E> removeLast = s.prev;return removeLast.value;}@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic boolean isFull() {return size == capacity;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = s.next;@Overridepublic boolean hasNext() {return p != s;}@Overridepublic E next() {E e = p.value;p = p.next;return e;}};}
}

2.循环数组实现

public class ArrayDeque3<E> implements Deque<E>, Iterable<E> {E[] array;int head;int tail;@SuppressWarnings("all")public ArrayDeque3(int capacity) {if ((capacity & capacity - 1) != 0) {throw new IllegalArgumentException("capacity 必须是2的幂");}array = (E[]) new Object[capacity];}/*ht0   1   2   3   4   5   6   70   1   2   3   4   5      -1h0   1   2   31           2*/@Overridepublic boolean offerFirst(E e) {if (isFull()) {return false;}array[--head & array.length - 1] = e;return true;}@Overridepublic boolean offerLast(E e) {if (isFull()) {return false;}array[tail++ & array.length - 1] = e;return true;}@Overridepublic E pollFirst() {if (isEmpty()) {return null;}int idx = head++ & array.length - 1;E e = array[idx];array[idx] = null; // help GCreturn e;}@Overridepublic E pollLast() {if (isEmpty()) {return null;}int idx = --tail & array.length - 1;E e = array[idx];array[idx] = null; // help GCreturn e;}@Overridepublic E peekFirst() {if (isEmpty()) {return null;}return array[head & array.length - 1];}@Overridepublic E peekLast() {if (isEmpty()) {return null;}return array[tail-1 & array.length - 1];}@Overridepublic boolean isEmpty() {return tail - head == 0;}/*head=-40   1   2   3a   d   c   b*/@Overridepublic boolean isFull() {return tail - head == array.length - 1;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = head;@Overridepublic boolean hasNext() {return p != tail;}@Overridepublic E next() {return array[p++ & array.length - 1];}};}
}

3.阻塞队列(双锁实现)

注意虚假唤醒的问题!

public class BlockingQueue3<E> implements BlockingQueue<E>{//模拟队列private E[] array;private final ReentrantLock headLock = new ReentrantLock();private Condition headWait = headLock.newCondition();private int head;private final ReentrantLock tailLock = new ReentrantLock();private Condition tailWait = tailLock.newCondition();private int tail;private AtomicInteger size = new AtomicInteger(0);public BlockingQueue3(int capacity) {this.array = (E[]) new Object[capacity];}@Overridepublic void offer(E e) throws InterruptedException {int c;tailLock.lockInterruptibly();try {while (isFull()){tailWait.await();}array[tail] = e;tail = (tail + 1) % array.length;c = size.getAndDecrement();} finally {tailLock.unlock();}headLock.lockInterruptibly();try {headWait.signal();} finally {headLock.unlock();}}@Overridepublic boolean offer(E e, long timeout) throws InterruptedException { // 毫秒 5sint c;tailLock.lockInterruptibly();long t = TimeUnit.MILLISECONDS.toNanos(timeout);try {while (isFull()){if (t <= 0){//主要虚假唤醒的问题 线程1唤醒了它 结果另一个线程2又给它放满了return false;}t = tailWait.awaitNanos(t);}array[tail] = e;tail = (tail + 1) % array.length;c = size.getAndDecrement();} finally {tailLock.unlock();}headLock.lockInterruptibly();try {headWait.signal();return true;} finally {headLock.unlock();}}@Overridepublic E poll() throws InterruptedException {int c;E e;headLock.lockInterruptibly();try {while(isEmpty()){headWait.await();}e = array[head];array[head] = null;head = (head + 1) % array.length;c = size.getAndDecrement();} finally {headLock.unlock();}tailLock.lockInterruptibly();try {tailWait.signal();} finally {tailLock.unlock();}return e;}private boolean isEmpty(){return size.get() == 0;}private boolean isFull(){return size.get() == array.length;}@Overridepublic String toString() {return Arrays.toString(array);}
}

二.栈(可以记住来时的路)

1.单向链表实现

    static class Node<E> {E value;Node<E> next;public Node(E value, Node<E> next) {this.value = value;this.next = next;}}private Node<E> head = new Node<>(null, null);private int capacity = Integer.MAX_VALUE;private int size = 0;public LinkedListStack(int capacity){this.capacity = capacity;}public LinkedListStack(){}@Overridepublic boolean push(E value) {if (isFull()){return false;}Node<E> next = head.next;Node<E> added = new Node<>(value, next);added.next = next;size++;return true;}@Overridepublic E pop() {if (isEmpty()){return null;}Node<E> removed = head.next;head.next = head.next.next;return removed.value;}@Overridepublic E peek() {if (isEmpty()){return null;}Node<E> removed = head.next;return removed.value;}@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic boolean isFull() {return size == capacity;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = head;@Overridepublic boolean hasNext() {return p != null;}@Overridepublic E next() {E value = p.value;p = p.next;return value;}};}

2.数组实现

    private final E[] array;//栈顶指针private int tail;private int capacity = Integer.MAX_VALUE;@SuppressWarnings("all")public ArrayStack(int capacity){this.array = (E[]) new Object[capacity];}@Overridepublic boolean push(E value) {if (isFull()){return false;}array[tail++] = value;return true;}@Overridepublic E pop() {if (isEmpty()) {return null;}E removed = array[--tail];return removed;}@Overridepublic E peek() {if (isEmpty()) {return null;}E removed = array[tail - 1];return removed;}@Overridepublic boolean isEmpty() {return tail == 0;}@Overridepublic boolean isFull() {return tail == array.length;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = tail;@Overridepublic boolean hasNext() {return p > 0;}@Overridepublic E next() {E value = array[--p];return value;}};}

3.力扣20题(有效括号)

思路:

遇到左括号就将其对应的右括号压入栈中,遇到右括号就弹出栈顶元素,看是否与这个有括号匹配。直到弹空

    public boolean isValid(String s) {ArrayStack<Character> stack = new ArrayStack<>(s.length());for (int i = 0; i < s.length(); i++){char c = s.charAt(i);if (c == '('){stack.push(')');}else if (c == '['){stack.push(']');}else if (c == '{'){stack.push('}');}else {if (!stack.isEmpty() && c == stack.peek()){stack.pop();}else {return false;}}}return stack.isEmpty();}


文章转载自:

http://rtXzJrsT.qjrjs.cn
http://AMVbZ1D5.qjrjs.cn
http://HFU9IvNw.qjrjs.cn
http://n2mDiV00.qjrjs.cn
http://pYBzKltO.qjrjs.cn
http://FBu40Ysv.qjrjs.cn
http://Qtt0NgXC.qjrjs.cn
http://uHnGjn5R.qjrjs.cn
http://4iUl31fi.qjrjs.cn
http://9S5y0iMn.qjrjs.cn
http://EiFc43H3.qjrjs.cn
http://fjq8HfnV.qjrjs.cn
http://7oYvnSGG.qjrjs.cn
http://eObWAw8j.qjrjs.cn
http://be3OELSN.qjrjs.cn
http://6b6cGQ6L.qjrjs.cn
http://xIUnbgQT.qjrjs.cn
http://fFQotv7K.qjrjs.cn
http://kSSKglia.qjrjs.cn
http://iwYFmVvC.qjrjs.cn
http://MTzpjFg4.qjrjs.cn
http://fvri957P.qjrjs.cn
http://q9pErgOc.qjrjs.cn
http://WFNMTYhQ.qjrjs.cn
http://XSZPatS8.qjrjs.cn
http://b5AamQ1R.qjrjs.cn
http://E1YkQinm.qjrjs.cn
http://NR1KJ9EH.qjrjs.cn
http://2Mbfwwk2.qjrjs.cn
http://eh4FDM6F.qjrjs.cn
http://www.dtcms.com/a/387101.html

相关文章:

  • 任天堂官网更新!“任亏券”不支持兑换NS2专用游戏
  • 大模型数据整理器打包及填充、Flash Attention 2解析(97)
  • 48v转12v芯片48v转5v电源芯片AH7691D
  • Oracle Database 23ai 内置 SQL 防火墙启用
  • MySQL 31 误删数据怎么办?
  • 微前端面试题及详细答案 88道(09-18)-- 核心原理与实现方式
  • VBA技术资料MF362:将窗体控件添加到字典
  • 【Leetcode】高频SQL基础题--1321.餐馆营业额变化增长
  • Redis 中 Intset 的内存结构与存储机制详解
  • uniapp打包前端项目
  • cka解题思路1.32-3
  • 如何解决模型的过拟合问题?
  • 2025牛客周赛108场e题
  • 【课堂笔记】复变函数-2
  • 25、优化算法与正则化技术:深度学习的调优艺术
  • qt QCategoryAxis详解
  • 云游戏时代,游戏盾如何保障新型业务的流畅体验
  • 【Block总结】LRSA,用于语义分割的低分辨率自注意力|TPAMI 2025
  • PY32MD310单片机介绍 电机控制专用,内置三相半桥栅极驱动器
  • Ubuntu服务器挖矿病毒清理
  • 【数据结构】——二叉树
  • 《怪物猎人 荒野》总整理:预载和开放时间、登场怪物
  • web服务解析案例
  • 莫烦Python基础笔记(部分)
  • ACP(四):RAG工作流程及如何创建一个RAG应用
  • qgis导入cad怎么做?
  • 在线图书借阅平台的设计与实现 —— 基于飞算JavaAI的实战开发全流程与优化实践(架构设计与核心模块开发)
  • Spring Cloud - 面试知识点(服务雪崩)
  • 【JQ】使用JS在前端达到存储cookie的效果
  • Git企业开发--分支管理