Java 栈和队列

文章目录

  1. 先进后出的方式组织数据

模拟实现栈

  1. 数组组织栈
java 复制代码
package Stack;

import java.util.Arrays;

public class MyStack implements IStack{
    private int[] elem;
    private int usedSize;
    private static final int DEFAULT_CAPACITY = 10;

    public MyStack(){
        elem = new int[DEFAULT_CAPACITY];
    }

    public boolean full(){
        if(usedSize == elem.length){
            return true;
        }
        return false;
    }

    @Override
    public void push(int x) {
        if(full()){
            elem = Arrays.copyOf(elem,2*elem.length);
        }
        elem[usedSize++] = x;
    }

    @Override
    public int pop() {
        if(empty()){
            // 抛异常
            throw new EmptyException("栈空了");
        }
        int k = usedSize;
        usedSize--;
        // 相当于删除
        // 如果是引用类型
        // elem[usedSize] = null;

        return elem[k-1];
    }

    @Override
    public int peek() {
        if(empty()){
            throw new EmptyException("栈为空");
        }

        return elem[usedSize - 1];
    }

    @Override
    public int size() {
        return usedSize;
    }

    @Override
    public boolean empty() {
        return usedSize == 0;
    }
}
  1. 用链表实现栈
    可以用双向链表实现栈

面试题

逆波兰表达式
有效的括号
栈的压入,弹出序列
最小栈

栈,虚拟机栈,栈桢

  1. 栈:是一种数据结构
  2. 虚拟机栈:是JVM开辟的一块内存
  3. 栈桢:是函数调用时在虚拟机中给这个方法开辟的一块内存

队列

  1. 队列:组织数据的方式是先进先出,队尾入数据,队头出数据

  2. add和offer都是入队,remove和poll都是删除元素,element和peek都是获取队头元素

模拟实现队列

  1. 使用双向链表模拟实现队列
  2. 入栈,出栈,获取栈顶元素,获取栈的大小,判空
java 复制代码
package queuedemo;

public class MyLinkQueue {

     static class ListNode{
         public int val;
         public ListNode next;
         public ListNode prev;

         public ListNode(int val){
             this.val = val;
         }
     }

     public int usedSize;
     public ListNode head;
     public ListNode last;

     // 链表的尾插法
     public boolean offer(int val){
         ListNode node = new ListNode(val);
         if(head == null){
             head = node;
             last = node;
         }else{
             last.next = node;
             node.prev = last;
             last = node;
         }

         usedSize++;

         return true;
     }

     // 头删
     public int poll(){
         ListNode node;
         if(!isEmpty()){
             node = head;
             head = head.next;
             if(head != null){
                 head.prev = null;
             }else{
                 last = null;
             }
         }else{
             throw new NullIndexException("队列为空");
         }

         usedSize--;

         return node.val;
     }

     // 获取队头元素
     public int peek(){
         if(head == null){
             return -1;
         }

         return head.val;
     }

     public boolean isEmpty(){
         return head == null;
     }

     public int size(){
         return usedSize;
     }
}

循环队列

  1. 数组可以实现队列吗?

循环队列

  1. rear是可以存放数组元素的下标
  1. 如何判断队列是空和满?
    浪费一个空间来表示满

如果front == rear,那么就是空

如果front的下一个空间是rear,那么就是满


使用usedSize来记录是否满了

使用标记

第一次相遇标记一下,第二次相遇再标记一下,证明是满了

rear =(rear + 1)% len 表示下一个位置的下标

rear + 1 == front 表示满

front = (front + 1) % len

  1. rear如何从7下标来到0下标?


循环队列

java 复制代码
class MyCircularQueue {

    public int[] elem;
    public int front;// 队头
    public int rear;// 队尾
    
    public MyCircularQueue(int k) {
        // 我们有一个空间要浪费掉
        elem = new int[k + 1];
    }

    // 入队
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }

        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        
        return true;
    }
    
    // 出队
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }
        
        // 出队,front++
        front = (front + 1) % elem.length;
        return true;
    }
    
    // 获取队头元素
    public int Front() {
        if(!isEmpty()){
            return elem[front];
        }

        return -1;
    }
    
    // 获取队尾元素
    public int Rear() {
        // rear - 1
        // (rear + elem.length - 1) % elem.length;
        if(!isEmpty()){
            int k = (rear + elem.length - 1) % elem.length;
            // int k = (rear == 0) ? elem.length - 1 : rear - 1;  
            return elem[k];
        }

        return -1;
    }
    
    public boolean isEmpty() {
        return front == rear;
    }
    
    public boolean isFull() {
        int k = (rear + 1) % elem.length;

        return k == front;       
    }
}

双端队列

  1. 可以从头进,从头出,从尾入,从尾出
  2. 不仅可以当做队列和栈还可以当做链表
java 复制代码
// 链表的双端队列
Deque<Integer> deque = new LinkedList<>();
// (顺序的)数组双端队列
Deque<Integer> deque1 = new ArrayDeque<>();

面试题

用队列实现栈

用栈实现队列
出队的时候如果两个栈中都有元素,先把第二个栈中的元素出完,再把第一个栈中的元素全部倒入第二个栈中,再出第二个栈中的元素

相关推荐
玩代码30 分钟前
备忘录设计模式
java·开发语言·设计模式·备忘录设计模式
BUTCHER51 小时前
Docker镜像使用
java·docker·容器
岁忧1 小时前
(nice!!!)(LeetCode 面试经典 150 题 ) 30. 串联所有单词的子串 (哈希表+字符串+滑动窗口)
java·c++·leetcode·面试·go·散列表
技术猿188702783511 小时前
实现“micro 关键字搜索全覆盖商品”并通过 API 接口提供实时数据(一个方法)
开发语言·网络·python·深度学习·测试工具
放飞自我的Coder2 小时前
【colab 使用uv创建一个新的python版本运行】
开发语言·python·uv
艾莉丝努力练剑2 小时前
【数据结构与算法】数据结构初阶:详解顺序表和链表(四)——单链表(下)
c语言·开发语言·数据结构·学习·算法·链表
zyhomepage2 小时前
科技的成就(六十九)
开发语言·网络·人工智能·科技·内容运营
珊瑚里的鱼2 小时前
第十三讲 | map和set的使用
开发语言·c++·笔记·visualstudio·visual studio
逑之2 小时前
C++笔记1:命名空间,缺省参数,引用等
开发语言·c++·笔记
songroom2 小时前
【转】Rust: PhantomData,#may_dangle和Drop Check 真真假假
开发语言·后端·rust