• 栈和队列的基本使用


    目录

    1.栈(Stack)

    1.1概念

    1.2 栈的实现

     2.队列(Queue)

    2.1 概念

    2.2 单链表实现队列

     2.3 循环队列

     2.4双端队列

    3.java 中的栈和队列


    1.栈(Stack)

    1.1概念

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

    压栈:栈的插入操作叫做进栈/压栈/入栈,如数据在栈顶。

    出栈:栈的删除操作叫做出栈。出数据在栈顶

    1.2 栈的实现

    1)利用顺序表实现,即使用尾插+尾删的方式实现

    2)利用链表实现,则头尾都可以

    因为顺序表实现上更为简单,此处使用顺序表实现

    1.创建 MyStack 类

    1. import java.util.Arrays;
    2. /**
    3. * 栈的实现
    4. */
    5. public class MyStack {
    6. public int[] elem;
    7. public int usedSize;
    8. public MyStack() {
    9. this.elem = new int[5];
    10. }
    11. //压栈
    12. public void push(int val) {
    13. if(isFull()) {
    14. //满了就2倍扩容
    15. this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
    16. }
    17. this.elem[this.usedSize] = val;
    18. this.usedSize++;
    19. }
    20. public boolean isFull() {
    21. return this.usedSize == this.elem.length;
    22. }
    23. //出栈,pop 会删除栈元素,peek 获取栈元素,不删除
    24. public int pop() {
    25. if(isEmpty()) {
    26. throw new RuntimeException("栈为空!");
    27. }
    28. int oldVal = this.elem[usedSize-1];
    29. this.usedSize--;
    30. return oldVal;
    31. }
    32. public int peek() {
    33. if(isEmpty()) {
    34. throw new RuntimeException("栈为空!");
    35. }
    36. int oldVal = this.elem[usedSize-1];
    37. return oldVal;
    38. }
    39. //判断栈是否为空
    40. public boolean isEmpty() {
    41. return this.usedSize == 0;
    42. }
    43. }

    2.main 函数

    1. import java.util.Stack;
    2. /**
    3. * 栈,先进后出
    4. */
    5. public class StackTest {
    6. public static void main(String[] args) {
    7. MyStack stack = new MyStack();
    8. //压栈
    9. stack.push(1);
    10. stack.push(2);
    11. stack.push(3);
    12. stack.push(4);
    13. stack.push(5);
    14. stack.push(6);
    15. //出栈,pop 是出一个栈顶元素并且在栈中删除
    16. System.out.println(stack.pop());//6
    17. // peek 是获取栈顶元素但不删除栈中元素
    18. System.out.println(stack.peek());//5
    19. System.out.println(stack.peek());//5
    20. System.out.println(stack.isEmpty());//false
    21. }
    22. }

    3.运行结果

     2.队列(Queue)

    2.1 概念

    队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 先进先出。
    入队列:进行插入操作的一端称为 队尾。
    出队列:进行删除操作的一端称为 队头。

    2.2 单链表实现队列

    队列也可以用数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

     单链表实现

    1. /**
    2. * 队列的实现,使用单链表
    3. */
    4. class Node {
    5. public int val;
    6. public Node next;
    7. public Node(int val) {
    8. this.val = val;
    9. }
    10. }
    11. public class MyQueue {
    12. public Node head;
    13. public Node last;
    14. /**
    15. * 添加队列元素
    16. * 使用单链表尾插法
    17. * @param val
    18. */
    19. public void offer(int val) {
    20. Node node = new Node(val);
    21. if (head == null) {
    22. head = node;
    23. last = node;
    24. }else {
    25. last.next = node;
    26. last = last.next;
    27. }
    28. }
    29. /**
    30. * 出队
    31. * @return
    32. */
    33. public int poll() {
    34. if (isEmpty()) {
    35. throw new RuntimeException("队列为空");
    36. }
    37. int oldVal = head.val;
    38. this.head = head.next;
    39. return oldVal;
    40. }
    41. public boolean isEmpty() {
    42. return this.head == null;
    43. }
    44. /**
    45. * 获取队列元素
    46. * @return
    47. */
    48. public int peek() {
    49. if (isEmpty()) {
    50. throw new RuntimeException("队列为空");
    51. }
    52. return head.val;
    53. }
    54. }

    main 方法

    1. import java.util.Queue;
    2. public class QueueTest {
    3. public static void main(String[] args) {
    4. MyQueue queue = new MyQueue();
    5. //入队列
    6. queue.offer(1);
    7. queue.offer(2);
    8. queue.offer(3);
    9. //获取队列元素
    10. System.out.println(queue.peek());//1
    11. //出队
    12. System.out.println(queue.poll());//1
    13. System.out.println(queue.poll());//2
    14. System.out.println(queue.poll());//3
    15. }
    16. }

    效果

     2.3 循环队列

    实际中我们有时还会使用一种队列叫循环队列。如操作系统在生产者消费者模型时可以就会使用循环队列。环形队列通常使用数组实现。

     代码

    1. /**
    2. * 设计循环队列
    3. */
    4. public class MyCircularQueue {
    5. public int[] elem;
    6. public int front;//队头下标
    7. public int rear;//队尾下标
    8. public MyCircularQueue(int k) {
    9. this.elem = new int[k + 1];
    10. }
    11. /**
    12. * 入队
    13. * @param value
    14. * @return
    15. */
    16. public boolean enQueue(int value) {
    17. if (isFull()) return false;
    18. this.elem[rear] = value;
    19. rear = (rear+1) % elem.length;
    20. return true;
    21. }
    22. /**
    23. * 出队
    24. * @return
    25. */
    26. public boolean deQueue() {
    27. if (isEmpty()) return false;
    28. front = (front+1) % elem.length;
    29. return true;
    30. }
    31. /**
    32. * 得到对头元素
    33. * @return
    34. */
    35. public int Front() {
    36. if (isEmpty()) return -1;
    37. return elem[front];
    38. }
    39. /**
    40. * 队尾元素
    41. * @return
    42. */
    43. public int Rear() {
    44. if (isEmpty()) return -1;
    45. int index = -1;
    46. if (rear == 0) {
    47. index = elem.length - 1;
    48. }else {
    49. index = rear - 1;
    50. }
    51. return elem[index];
    52. }
    53. public boolean isEmpty() {
    54. return front == rear;
    55. }
    56. public boolean isFull() {
    57. if((this.rear+1) % elem.length == front) {
    58. return true;
    59. }
    60. return false;
    61. }
    62. }

     2.4双端队列

    双端队列( deque )是指允许两端都可以进行入队和出队操作的队列, deque “double ended queue” 的简称。 那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

    3.java 中的栈和队列

    Stack
    方法
    解释
    E push (E item)
    压栈
    E pop ()
    出栈
    E peek ()
    查看栈顶元素
    boolean empty()查看栈是否为空

    Queue

    入队列
    add(e)
    offer(e)
    出队列
    remove()
    poll()
    队首元素
    element()
    peek()
    错误处理抛出异常返回特殊值

  • 相关阅读:
    u盘损坏无法读取怎么恢复数据?
    Mock.js用法详解
    Win10中的核心隔离和内存完整性是什么?
    进程相关内容(三)
    推荐计划为什么有效?需要推荐计划的10个原因
    【WebGIS面试经验】(四)第一次社招面试也是第一次线下面试
    [c++]你最喜爱的stringstream和snprintf性能深入剖析
    Nowa Flutter开发教程之 01 什么是Nowa?真能无代码构建 Flutter 应用程序么?
    [Java、Android面试]_20_Android的四种启动模式(高频问题)
    Electron+Vue3整合-开发时整合-全部ts开发 + 一条命令启动vue3和electron两个服务
  • 原文地址:https://blog.csdn.net/m0_60494863/article/details/125291875