【数据结构】栈和队列详解!!!--Java

目录

一、🍰栈(Stack)

1.🥧什么是栈?

🍦栈

🍦栈的特点

2.🥧栈的使用

3.🥧栈的模拟实现

4.🥧栈的优缺点

🍦优点:

🍦缺点:

二、🍰队列(Queue)

1.🥞什么是队列?

🍦队列

🍦队列的特点

2.🥞队列的使用

🍦实例化

🍦Queue中的方法

🍦队列的使用

3.🥞队列模拟实现

4.🥞队列的优缺点

🍦优点:

🍦缺点:


一、🍰栈(Stack)

1.🥧什么是栈?

🍦栈

栈是一种数据结构,他是一种只允许 在一端固定进行插入和删除操作的特殊线性表。先进入 的数据被压入栈底最后进入 的数据被放在栈顶 ,需要读出的数据从栈顶开始弹出 ,按照先入后出的原则。

操作:

入栈:也称为压栈/进栈 ,将插入 的元素放在栈顶;

出栈: 将栈顶 的元素进行删除;

🍦栈的特点

  • 操作受限性只允许一端固定进行插入和删除操作,不像顺序表可以进行任意的插入和删除;
  • 数据存储的有序性 :元素遵循先进后出 的原则,即先入栈的元素后出栈
  • 空间效率 :无需像数组等数据结构分配存储大量的固定空间,可以根据元素的入栈和出栈发生动态变化,可以避免空间的浪费;
  • 时间复杂度出栈和出栈 的时间复杂度都为O(1),操作效率高;

2.🥧栈的使用

栈的方法

|-----------------|------------|
| 方法 | 功能 |
| Stack() | 构造一个空的栈 |
| E push(E e) | 将元素入栈 |
| E pop() | 将元素出栈 |
| E peek() | 获取栈顶元素 |
| int size() | 获取栈中有效个数大小 |
| boolean empty() | 判断栈是否为空 |

细心的同学观察图片和表格中的方法会发现,图片中并没有size方法,是因为Stack继承于Vector,他使用的size方法是Vector中的方法;

什么是Vector?

  • Vector继承与List接口,他与ArrayList相似,与ArrayList不同的是,Vector是线程安全,当其相对性能较低。在当线程的情况下,如果不需要线程安全,更推荐ArrayList。

什么是线程安全?

  • 线程安全指的是在多线程的环境下,程序或代码能过正确地运行,不会出现数据不一致、竞争条件、死锁等问题。

方法的使用:

java 复制代码
    public static void main(String[] args) {
        Stack<Integer> stack=new Stack<>();
        //入栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        //获取有效个数大小
        System.out.println(stack.size());//3
        //获取栈顶元素
        System.out.println(stack.peek());//3
        //出栈
        stack.pop();
        //获取栈顶元素
        System.out.println(stack.peek());//2
        //查找元素下标
        System.out.println(stack.search(2));
    }

3.🥧栈的模拟实现

java 复制代码
//数组模拟实现栈
public class MyStack {
    //元素
    public int[] n;
    //有效元素大小
    public int usedsize;
    //构造方法
    public MyStack(int[] n) {
        this.n = n;
    }
    //入栈:将元素进行插入
    //1.判断是否满了,满了用Arrays.copyOf进行扩容
    //1.用元素放入数组中,
    //2.元素个数增加
    public void push(int x){
        if(isFull()){
          this.n= Arrays.copyOf(n,2*n.length);
        }  
        n[usedsize]=x;
         usedsize++;
    }
    private boolean isFull(){
        return usedsize==n.length;
    }
    //出栈:将栈顶元素拿出
    //1.判断栈是否为空;
    // 2.将栈中元素减减即可
    public int pop(){
        if(empty()){
            return -1;
        }
        int val=n[usedsize-1];
         usedsize--;
         return val;
    }
    //获取栈顶元素
    //1.判断栈是否为空,如果为空抛出异常
    // 2.获取栈中元素
    public int peek(){
        if(empty()){
             throw new EmptyStackException();
        }
        return n[usedsize-1];
    }
    //判断栈是否为空
    //看其有效个数是否为0
    public boolean empty()throws EmptyStackException{
          return this.usedsize==0;
    }
}

可以通过链表来模拟实现栈吗?

答案是:可以的

1.如果采用单链表来实现:

  • 采用的是头插法,入栈和出栈的时间复杂度都为O(1);
  • 采用的是尾插法,入栈的时间复杂度为O(n),如果有last,那么时间复杂度为O(1),但是出栈时间复杂度一定是O(n);

2.如果采用双链表来实现:

  • 不管是头插法和尾插法都可以实现;

4.🥧栈的优缺点

🍦优点:

  • 数据存储的有序性 :元素遵循先进后出 的原则,即先入栈的元素后出栈
  • 操作简单高效 :栈的入栈和出栈操作都在栈顶 进行,时间复杂度在为O(1) ,能迅速实现插入和删除;
  • 空间效率 :无需像数组等数据结构分配存储大量的固定空间,可以根据元素的入栈和出栈发生动态变化,可以避免空间的浪费;

🍦缺点:

  • 功能有限 :功能比较单一,只能在一端进行简单的插入和删除
  • 数据访问有限除栈顶元素外访问其他元素 需要一一弹出,操作麻烦且效率低
  • 存储容量问题 :虽然可以动态扩容,但是在大量元素入栈 的时候,栈的连续空间可能受内存限制;

二、🍰队列(Queue)

1.🥞什么是队列?

🍦队列

队列就像日常生活中的排队一样,一端用于插入元素 ,称为队尾 ;另一端用于删除元素 ,称为队头 。其遵循的的是先进先出 的原则。

操作:

  • 入队:插入元素在队尾;
  • 出队: 删除元素在队头;

🍦队列的特点

  • 顺序性:队列按照先进先出的原则;
  • 操作受限性:队列主要集中于队头和队尾;
  • 存储结构的多样性:队列可以通过不同的存储结构来实现,常见的有数组和链表;
  • 并发处理优势:在多线程或多任务环境中,队列常用于实现数据的缓冲和同步;
  • 空间利用效率:可以实现空间的动态调整,提高空间的利用效率,避免空间浪费;

队列的分类

  • 普通队列:普通队列是队列最基本的形式,遵循先进先出的原则;
  • 双端队列(Dequeue):双端队列允许两端进行插入和删除操作,元素可以从队头出队和入队;
  • 循环队列:循环列队是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的闭环;
  • 优先队列: 优先级队列中带有优先级元素,入队时按照优先级确定在队列中的位置,出队时总是优先级最高的元素先出队;这个得在二叉树学完才明白;
java 复制代码
 

2.🥞队列的使用

🍦实例化

Queue 是一个接口,不能实例化本身 ,但只要实现了这个接口都可以实例化,比如LinkedList、ArrayDeque以及PriorityQueue等等其他;

java 复制代码
 public static void main(String[] args) {
        Queue<Integer> queue=new LinkedList<>();
        Queue<Integer> queue1=new ArrayDeque<>();
        Queue<Integer> queue2=new PriorityQueue<>();
    }

🍦Queue中的方法

看下面的图片,我们可以发现他们分为两类使用效果相同,但是使用目的不同:

|--------------------|--------|
| 方法 | 功能 |
| boolean offer(E e) | 入列队 |
| E poll() | 出列队 |
| peek() | 获取队头元素 |
| int size() | 有效元素个数 |
| boolean isEmpty() | 判断是否为空 |

🍦队列的使用

java 复制代码
    public static void main(String[] args) {
        Queue<Integer> queue=new LinkedList<>();
        //入队
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        //获取有效元素个数
        System.out.println(queue.size());//3
        //获取队头元素
        System.out.println(queue.peek());//1
        //出队
        System.out.println(queue.poll());//1
    }

3.🥞队列模拟实现

普通队列用双链表模拟实现:

java 复制代码
public class MyQueue {
     //创建节点类
    static class ListNode{
        public int val;
        public ListNode prev;
        public ListNode next;

         public ListNode(int val) {
             this.val = val;
         }
     }
     public ListNode first=null;
     public ListNode last=null;
     public int usedSize=0;
     //入队
    //判断是否为空,如果为空将头尾节点都等于该新节点
    //如果不是,将节点添加到队尾
    //有效元素个数增加
    public void offer(int val){
        ListNode listNode=new ListNode(val);
        if(isEmpty()){
            first=last=listNode;
        }else{
            last.next=listNode;
            listNode.prev=last;
            last=listNode;
        }
        usedSize++;
    }
    //出队
    //判断队列是否为空;
    //出队头元素,将队头指针向后移动
    //使用元素个数减少
    public int poll(){
        if(isEmpty()){
            return -1;

        }
        int val= first.val;
        first=first.next;
        if(first!=null){
            first.prev=null;
        }
        return val;
    }
    //获取队头元素
    //判断队列是否为空
    //如果不为空,直接返回队头元素
    public int peek(){
        if(isEmpty()){
            return -1;
        }
        return first.val;
    }
    //判断是否为空
    //判断有效元素个数是否为0
    public boolean isEmpty(){
        return usedSize==0;
    }
}

4.🥞队列的优缺点

🍦优点:

  • 顺序处理:能保证顺序的依次处理;
  • 数据缓存:可作为数据缓存区。防止数据丢失;
  • 动态扩展:队列实现可以按需要实现动态扩展;

🍦缺点:

  • 访问受限:遵循先进先出原则;
  • 存储限制:通常有长度限制,如果超过容量会有数据丢失;
  • 性能问题:如果队列过长,可能会导致性能下降;
相关推荐
武昌库里写JAVA8 分钟前
16.React学习笔记.React更新机制
java·开发语言·spring boot·学习·课程设计
怒码ing28 分钟前
ArrayList、LinkedList、HashMap、HashTable、HashSet、TreeSet
java·集合
MickeyCV34 分钟前
Mybatis快速入门与核心知识总结
java·intellij-idea·mybatis·jdbc
Excuse_lighttime1 小时前
选择排序
java·开发语言·数据结构·算法·排序算法
Excuse_lighttime1 小时前
插入排序和希尔排序
java·开发语言·数据结构·算法·排序算法
☆cwlulu1 小时前
一句话总结一种排序算法,精炼
数据结构·算法·排序算法
胡晔可可1 小时前
数据库中存储时候将字段为空串时转换成null
java·数据库
爱是小小的癌1 小时前
数据结构与算法之排序算法-快速排序(分治)
java·开发语言·数据结构·算法·排序算法
✿ ༺ ོIT技术༻1 小时前
剑指offer第2版:搜索算法(二分/DFS/BFS)
数据结构·算法
技术小泽1 小时前
算法基础之排序算法大总结1!!
java·数据结构·后端·算法·排序算法