数据结构之—栈和队列

本文详细介绍了栈和队列这两种数据结构,包括它们的应用场景、实现方式以及常见操作。栈作为后进先出(LIFO)的数据结构,常用于撤销操作、浏览器历史记录等。队列则遵循先进先出(FIFO)原则,常用于任务调度。文中还讲解了循环队列的概念和判断满队列的条件,并通过LeetCode题目展示了如何用栈实现队列和队列实现栈。此外,文章还探讨了括号匹配问题和最小栈等栈的应用。
摘要由CSDN通过智能技术生成

目录

引言

一、栈(stack)

1.栈的应用

2.栈的实现

二、队列

1.基础队列的实现

2.循环队列 ​编辑

1)概念

2)如何判断环形队列为空⭐

总结:环形队列是否已满条件:(tail+1)%data.length==head;

3)循环队列代码实现:

三、题目:

1.栈和队列的相互转化

1)用栈实现队列(leetcode232)

2)用队列实现栈(leetcode225)

进阶:用一个队列实现

2.栈的应用

1)括号匹配问题(leetcode20)

2)最小栈


接:集合类—List、Map、Set的简单用法_林纾y的博客-CSDN博客_map put列表

内部类和泛型_林纾y的博客-CSDN博客_内部类使用泛型

引言

        栈和队列都是线性表,都是基于List基础上的实现。栈和队列是一个使用上更加严格的线性表,动态数组,链表可以在任意位置进行元素的插入和删除,栈和队列不行,他们是一端插入一端删除。

        线性表:数组、链表、字符串、栈、队列(元素按照一条“直线”排列,线性表这个结构中,一次添加单个元素)

一、栈(stack)

        后进先出的线性表,支持三个核心操作:入栈push出栈pop返回栈顶元素 peek【水杯就是一个天然的栈结构,只能从杯口倒入水,从杯口倒出水】

LIFO:后进先出--Last In First Out

1.栈的应用

1)撤销操作:一般任意编译器中,撤销操作:ctrl+z

2)浏览器的前进后退:如此时页面在C页面,看完C后想返回B页面,点击后退箭头相当于将C出栈,此时栈顶就是B页面。

3)开发中程序的“调用栈”操作系统栈底层就是我们的栈实现。

分析:funA()卡在第二行入栈,funB()卡在第二行入栈,funC入栈,return开始就是出栈了

2.栈的实现

自己实现栈,栈也是一个线性表

1)基于数组实现的栈--顺序栈【数组尾部添加删除时间复杂度O(1)】,栈顶实际上就是数组末尾

2)基于链表实现的栈--链式栈【尾插和尾删】

代码:

import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * 基于数组的顺序栈实现
 * @param <E>
 */
public class MyStack<E> {
    //当前栈的数据个数
    private int size;
    //实际存储数据的动态数组-ArrayList-长度不够自动扩容
    private List<E> data=new ArrayList<>();
    /**
     * 将val入栈
     * @param val
     */
    public void push(E val){
        //默认List集合的add是尾插
        data.add(val);
        size++;
    }

    /**
     * 弹出栈顶元素,返回栈顶的值
     * @return
     */
    public E pop(){
        if(isEmpty()){
            //栈为空,没有栈顶元素,抛出异常
            throw new NoSuchElementException("stack is empty!cannot pop!");
        }
        //删除栈顶元素
        E val=data.remove(size-1);
        size--;
        return val;
        //这三行可写成一句:return data.remove(--size);
    }

    /**
     * 返回栈顶元素,但不出栈
     * @return
     */
    public E peek(){
        if(isEmpty()){
            throw new NoSuchElementException("stack is empty!cannot peek!");
        }
        return data.get(size-1);
    }

    /**
     * 返回当前栈顶元素是否为空
     * @return
     */
    public boolean isEmpty(){
        return size==0;
    }

    /**
     * 打印栈的元素
     * @return
     */
    @Override
    public String toString() {
     StringBuilder sb=new StringBuilder();
     sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(data.get(i));
            if(i!=size-1){
                sb.append(",");
            }
        }
        sb.append("] top");
     return sb.toString();
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        MyStack<Integer> myStack=new MyStack<>();
        myStack.push(1);
        myStack.push(3);
        myStack.push(5);
        System.out.println(myStack.toString());
        while(!myStack.isEmpty()){
            System.out.println(myStack.pop());
        }
    }
}

二、队列

FIFO:在队首出队,在队尾入队,先进先出的数据结构

食堂排队就是队列结构

1.基础队列的实现

1)基于数组实现的队列--顺序队列

2)基于链表实现的队列--链式队列(优)

        由于队列是队尾入队,队首出队,队首出队如果用数组就是数组的头部删除,时间复杂度为O(n),此时使用链表会更好,在链表尾部插入,头部删除,或者尾删头插。

 头删尾插举例:

/**
 * 将队列设计为接口,泛型接口(支持多种类型)
 * @param <E>
 */
public interface Queue<E> {
    //入队
    void offer(E val);
    //出队
    E poll();
    //返回队首元素
    E peek();
    //队列是否为空
    boolean isEmpty();
}

实现接口:

import java_1_24.stack_queue.queue.Queue;
import java.util.NoSuchElementException;

/**
 * 队列的实现
 * 基于链表实现的基础队列
 */
public class MyQueue<E> implements Queue<E> {
    //节点--用成员内部类-链表的每个节点
    private class Node{
        E val;
        Node next;
        public Node(E val) {
            this.val = val;
        }
    }
    //当前队列元素个数
    private int size;
    //链表队首
    private Node head;
    //队尾
    private Node tail;
    //入队-尾插
    @Override
    public void offer(E val) {
        Node node=new Node(val);
        if(head==null){
            //此时队列为空(头节点都为空尾也肯定为空)
            head=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值