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<>();

面试题

用队列实现栈

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

相关推荐
0110_102410 分钟前
tauri + rust的环境搭建---初始化以及构建
开发语言·后端·rust
会开花的二叉树11 分钟前
C++微服务 UserServer 设计与实现
开发语言·c++·微服务
像风一样自由202015 分钟前
Rust Tokio vs Go net/http:云原生与嵌入式生态选型指南
开发语言·golang·rust
DuHz17 分钟前
C程序中的数组与指针共生关系
linux·c语言·开发语言·嵌入式硬件·算法
我星期八休息20 分钟前
C++智能指针全面解析:原理、使用场景与最佳实践
java·大数据·开发语言·jvm·c++·人工智能·python
摇滚侠20 分钟前
Spring Boot 3零基础教程,WEB 开发 整合 Thymeleaf 笔记36
java·spring boot·笔记
大猫会长25 分钟前
docker安装php+apache
java·开发语言
野生技术架构师27 分钟前
JAVA 架构师面试题含答案:JVM+spring+ 分布式 + 并发编程
java·jvm·spring
道之极万物灭39 分钟前
Go小工具合集
开发语言·后端·golang
瑞士卷@39 分钟前
MyBatis入门到精通(Mybatis学习笔记)
java·数据库·后端·mybatis