首页 > 其他分享 >数据结构_栈和队列

数据结构_栈和队列

时间:2024-06-20 12:29:53浏览次数:23  
标签:队列 元素 int array 数据结构 public rear

目录

一、栈

1.1 栈的使用

1.2 模拟实现栈

二、队列

2.1 队列的使用

2.2 环形队列

2.3 双端队列

总结


一、栈

是只允许在固定的一端进行元素的插入和删除操作的一种特殊线性表。其中进行元素的插入和删除操作的一端称为栈顶,另一端称为栈底。栈遵循先进后出 (后进先出) 原则。

入栈:栈的插入操作称为入栈/进栈/压栈,入数据在栈顶

出栈:栈的删除操作称为出栈,出数据在栈顶

1.1 栈的使用

在 Java 中,提供了 Stack 类来表示栈。

【栈方法】

方法功能
E push(E e)将 e 入栈,并返回
E pop()将栈顶元素出栈,并返回
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()判断栈中是否为空

1.2 模拟实现栈

首先定义定义数组来实现栈、usedSize 记录栈中有效元素个数、并定义其默认容量及其构造方法。

    //数组实现栈
    private int[] array;
    //栈中有效元素个数
    private int usedSize = 0;
    //栈默认容量
    private static final int DEFAULT_CAPACITY = 10;

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

1、push():入栈

    public void push(int e) {
        //若栈已满,则扩容
        if (full()) {
            array = Arrays.copyOf(array, 2*array.length);
        }
        //usedSize标记着栈中元素个数的同时,
        //由于下标从 0 开始计数,元素个数从 1 开始计数
        //所以 usedSize 可以视为栈顶元素下标 +1
        array[usedSize] = e;

        usedSize++;
    }
    //是否已满
    public boolean full() {
        return usedSize == array.length;
    }

 usedSize 做当前可存放元素的下标:

2、pop():栈顶元素出栈,并返回

    public int pop() {
        //若栈为空,则抛异常
        if (empty()) {
            throw new EmptyException("栈为空!");
        }
        //创建变量接收原栈顶元素
        int old = array[usedSize-1];

        //栈顶元素被获取
        usedSize--;

        //返回原栈顶元素
        return old;
    }

3、peek():获取栈顶元素 

    public int peek() {
        //栈中有效个数为 0,抛异常
        if (usedSize == 0) {
            throw new EmptyException("栈为空!");
        }
        //返回栈顶元素
        return array[usedSize-1];
    }

4、size():获取栈中有效元素个数

    public int size() {
        //返回栈中有效元素个数
        return usedSize;
    }

5、empty():判断栈是否为空

    public boolean empty() {
        //若栈中有效个数为 0,则返回 true;反之 false
        return usedSize == 0;
    }


二、队列

队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的一种特殊线性表。队列遵循先进先出原则。

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

2.1 队列的使用

在 Java 中,提供了 Queue 接口来表示队列,其底层是通过链表实现的。由于 Queue 是一个接口,所以实例化队列时必须实例化 LinkedList 对象,因为 LinkedList 实现了 Queue 接口。

【队列方法】

方法功能
boolean offer(E e)入队列
E poll()出队列
E peek()获取队头元素
int size()获取队列内有效元素个数
boolean isEmpty()判断队列内是否为空
import java.util.LinkedList;
import java.util.Queue;

public class QueueDemo {
    public static void main(String[] args) {
        //创建一个空队列
        Queue<Integer> queue = new LinkedList<>();

        //入队列
        queue.offer(11);
        queue.offer(22);
        queue.offer(33);

        //获取队头元素
        System.out.println(queue.peek()); //11

        //获取队列中有效元素个数
        System.out.println(queue.size()); //3

        //出队列:先进先出
        queue.poll(); //11最先进入,故 11出队列

        //再次获取队头元素
        System.out.println(queue.peek()); //22

        System.out.println(queue.size()); //2

        //判断队列是否为空
        System.out.println(queue.isEmpty()); //false
    }
}

2.2 环形队列

环形队列还可以叫做循环队列,顾名思义,即当队列存放元素至队列尾后,此时可存放元素的下标再次循环至队列头,其通常使用数组实现。在生产者消费者模型中,就可以使用循环队列。

在实现环形队列之前,我们先定义变量 front 与 rear,front 表示队列头,rear 表示当前可以存放元素的下标。

此时就需要解决 rear 与 front 相遇时队列为空还是为满的问题,这里我们采用浪费一个空间来判断队列是否已满,即当 rear 的下一个就是 front 时,此时认为队列已满,需等 front 下标元素出队,才可再次存放元素。

同时,还需解决 rear 怎么从 5 下标前往 0 下标的问题,我们可以使用 (rear+1) % length 来决定当前存放元素的下标。

class MyCircularQueue {

    public int[] array; //定义数组实现环形队列
    public int front = 0; //队头,初始为 0
    public int rear = 0; //当前存放元素的下标,初始为 0

    public MyCircularQueue(int size) {
        array = new int[size];
    }

    //入队
    public boolean inQueue(int value) {
        //若队列已满,则 false
        if (isFull()) {
            return false;
        }
        //存入元素
        array[rear] = value;
        //为防止前往 0 下标时出错,故不用 rear++
        rear = (rear+1) % array.length;

        return true;
    }

    //出队
    public boolean outQueue() {
        //若队列为空,则 false
        if (isEmpty()) {
            return false;
        }
        //与 rear 同理,防止前往 0 下标时出错
        front = (front+1) % array.length;

        return true;
    }

    //获取队头元素
    public int Front() {
        //若队列为空,则 -1
        if (isEmpty()) {
            return -1;
        }
        //返回 front 下标元素
        return array[front];
    }

    //获取队尾元素
    public int Rear() {
        //若队列为空,则 -1
        if (isEmpty()) {
            return -1;
        }
        //队尾元素是处于 rear 下标的前一个,
        //若 rear 下标为 0,则队尾元素在队列最大下标处;
        //其余情况,队尾元素处于 rear-1 下标处。
        int tail = rear == 0 ? array.length-1 : rear-1;
        return array[tail];
    }
    
    //判断队列是否为空
    public boolean isEmpty() {
        //若 front 与 rear 相等,则队列为空
        return front == rear;
    }
    
    //判断队列是否已满
    public boolean isFull() {
        //若 rear 的下一个是 front,则队列已满
        return (rear+1) % array.length == front;
    }
}

2.3 双端队列

双端队列是指在队列两端都可以进行入队和出队的操作。Java 中提供 Deque 接口来表示双端队列。

【栈和队列均可使用 Deque 接口】

1、双端队列的线性实现:Deque<Integer> stack = new ArrayDeque<>();

2、双端队列的链式实现:Deque<Integer> queue = new LinkedList<>();


总结

1、栈遵循先进后出 (后进先出) 原则,队列遵循先进先出原则。

2、栈只允许在固定的一端进行元素的插入和删除操作。

3、队列只允许在一端进行插入数据操作,在另一端进行删除数据操作。

4、栈和队列均可使用 Deque 接口。 

标签:队列,元素,int,array,数据结构,public,rear
From: https://blog.csdn.net/m0_73620971/article/details/138361288

相关文章

  • leetcode225用队列实现栈
    本文主要讲解用队列实现栈的要点与细节,按照步骤思考更方便理解,同类型用栈实现队列c++与java代码如下,末尾请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。实现 MyStack 类:voidpush(intx) 将元素x压入栈顶。intp......
  • python队列实例解析
    一队列的概念1创建队列:importqueueq=queue.Queue()#创建Queue队列 2入队和出队foriinrange(3):q.put(i)#在队列中依次插入0、1、2元素foriinrange(3):print(q.get())#依次从队列中取出插入的元素,数据元素输出顺序为2、1、0......
  • [学习笔记] 树链剖分 - 图论 & 数据结构
    树链剖分怎么说呢,感觉只要不是求最大最小值好像都可以用树上查分代替。例题[ZJOI2008]树的统计-单点修改树链查询树链剖分板子,不多说了,代码注意细节就行。该用dfn的地方不要把点的编号传进去。#include<bits/stdc++.h>usingnamespacestd;#definels(id<<1)#define......
  • Java版-剑指offer数据结构与算法 视频教程 下载
    Java版-剑指offer数据结构与算法视频教程下载01-数据结构与算法入门基础clip.mp402-clip1.mp403-clip2.mp404-基础数据结构:数组&链表(一).mp405基础数据结构:数组&链表(二).mp406-基础数据结构:栈.mp407-基础数据结构:队列.mp408-算法思想:数论&枚举&递归&分治&回溯.mp409......
  • 考研系列-数据结构第五章:树与二叉树(上)
    目录写在前面:一、树的基本知识点1.树的基本概念2.树的常见术语(1)结点之间的关系描述(2)结点、树的属性描述(3)有序树和无序树对比(4)树和森林对比(5)总结3.树常考性质(1)结点数=总度数+1(2)度为m的树VSm叉树(3)树的层数(高度)和结点个数(4)求树最多/最少结点......
  • 【数据结构】顺序表
    Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎~~......
  • 代码随想录第12天 | 栈与队列part02(有题目未解决)
    题目:150.逆波兰表达式求值思路:1.使用栈,存储数字,遇到运算符,则取出栈顶两个数进行运算,结果在存入栈中。坑:加减乘除运算符没有别的技巧,就是if相等然后+-*/,switch也可以栈使用longlong型,int型会溢出使用"+"不是单引号'+',vector<string类型>不是vector<char类型>编......
  • 复习数据结构的第八天(串)
    串的概念字符串的概念很简单,就是一堆字符形成的有限序列。比如"看到这里的都是帅哥","abcdef"等都是字符串。而字符串字符的个数就是字符串的长度。通常一个字符串的结束标识是'\0'。对串的操作通常都是针对子串进行的,子串可以理解为就是一个字符串的子集,比如"帅哥"就是"看到......
  • 数据结构与算法-红黑树的java实现-构建红黑树
    红黑树红黑树是一种二分查找树,与普通的二分查找树不同的一点是,红黑树的每个节点都有一个颜色(color)属性。该属性的值要么是红色,要么是黑色。通过限制从根到叶子的任何简单路径上的节点颜色,红黑树确保没有比任何其他路径长两倍的路径,从而使树近似平衡。节点红黑树的节......
  • 列举几种常见的数据结构,以及线性数据结构
    数据结构是计算机科学中用来组织、存储和管理数据的方式。它定义了数据元素之间的逻辑关系,以及如何对数据进行操作。数据结构的选择对于算法的效率至关重要,因为它直接影响到数据在计算机中的存储和访问方式。以下是几种常见的数据结构:数组(Array):数组是一种线性数据结构,用......