【Java数据结构】栈与队列 经典面试题——刷题笔记(下)

简介: 笔记

4. 用栈实现队列


题目:

35.png


思路:

队列是先进先出,需要用到两个栈才能实现队列

指定S1为输入栈,S2为输出栈

入队时,直接将元素压入S1栈即可

出队时,要将输入栈S1中的元素依次出栈,并压入输出栈S2中,然后将S2栈顶元素出栈,这样就能实现先入队的元素先出队,有一点要注意,只有S2为空的时候,才能将输入栈S1中的元素移到S2中,不然会打乱队列顺序!

36.gif


实现代码:

class MyQueue {
    //创建两个栈
    Stack<Integer> s1;//输入栈
    Stack<Integer> s2;//输出栈
    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    public void push(int x) {
        s1.push(x);//入队直接将元素压入S1即可
    }
    public int pop() {
        int size = s1.size();//出队时,将s1中所以元素移至s2中
        if(!s2.isEmpty()){
            return s2.pop();//s2不为空,则直接弹出栈顶元素即可
        }else{
          for(int i=0; i<size; i++){//否则要将s1中元素转移到s2中再弹出s2栈顶元素
              int tmp = s1.pop();
              s2.push(tmp);
            }
        return s2.pop();
        }
    }
    public int peek() {//和出队方法一样,只不过由删除变成查看,只看不删
        int size = s1.size();
        if(!s2.isEmpty()){
            return s2.peek();
        }else{
          for(int i=0; i<size; i++){
              int tmp = s1.pop();
              s2.push(tmp);
            }
        return s2.peek();
        }
    }
    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }
}


5. 设计循环队列


题目:

37.png


思路:


要设计一个循环队列,用到的是一个数组,需要设置一个front下标表示队列首元素,rear下标,表示尾元素后一个可用位置的下标

有三个关键问题要解决:

①front和rear相遇之后,队列到底是空了还是满了?

答:每次再放元素的时候,都去判断rear位置的下一个位置是不是front,如果是,就满了,所以要预留一个空间,不放元素

②rear每次存放完成之后,能不能进行rear=rear+1

③front每次出队之后,能不能进行front=front+1

答:rear和front都不能直接+1,因为假设7个元素的循环队列,下标走到6了,6+1=7 数组此时能访问7下标嘛?不能,所以研究处一个公式rear/front = (rear/front+1)%len就能表示下一个位置了

38.gif



实现代码:


class MyCircularQueue {
    private int[] elem; //数组
    private int front;// 头
    private int rear;//尾巴下标   当前可以存放元素的下标
    public MyCircularQueue(int k) {
        //这里为什么是k+1: 题的描述指定要放k个,因为用我的方法实现的时候就是多一个空间出来的
        this.elem = new int[k+1];
        this.rear = 0;
        this.front = 0;
    }
    //入队
    public boolean enQueue(int value) {
        if(isFull()) //判断循环队列满了没有
        return false;//满了就返回false
        this.elem[this.rear] = value;//没满就给rear位置插入元素
        this.rear = (this.rear+1)%this.elem.length;//然后rear下标往后走一步
        //this.rear = this.rear+1;
        return true;
    }
    //删除  出队
    public boolean deQueue() {
         if(isEmpty()) {//先判断循环队列是否空
            return false;//空的就返回false
        }
        //循环队列不为空,就将首元素位置,front往后走一步
        //原来的元素会被以后加入的覆盖掉,或者不再能被访问到
        this.front = (this.front+1)%this.elem.length;
        return true;
    }
    //得到队头元素
    public int Front() {
         if(isEmpty()) {//依旧先判断是否为空
            return -1;
        }
        return this.elem[this.front];
    }
    //得到队尾元素  注意:当rear == 0下标的时候
    public int Rear() {
         if(isEmpty()) {//依旧先判断是否为空
            return -1;
        }
        //这里注意一个问题,我们已经知道rear-1位置就是队尾元素,可是当rear=0的时候,0-1=-1,这样不就出错了?所以遇到这种情况的时候用 循环队列的长度-1 就是0下标的上一个位置了
        int index = (this.rear == 0) ? this.elem.length-1 : this.rear-1;
        return this.elem[index];
    }
    public boolean isEmpty() {
        //只要他两相遇了 那么就是空的队列
        if(this.front == this.rear) {
            return true;
        }
        return false;
    }
    public boolean isFull() {
        //判断rear位置的下一个位置是不是front,如果是,就满了
        if((this.rear+1) % this.elem.length == this.front) {
            return true;
        }
        return false;
    }
}
相关文章
|
3月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
55 1
|
20天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
37 5
|
2月前
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
99 2
|
2月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
52 6
|
2月前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
3月前
|
存储 算法 Java
Java 中常用的数据结构
【10月更文挑战第20天】这些数据结构在 Java 编程中都有着广泛的应用,掌握它们的特点和用法对于提高编程能力和解决实际问题非常重要。
35 6
|
3月前
|
存储 Java 开发者
Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效
【10月更文挑战第19天】在软件开发中,随着项目复杂度的增加,数据结构的组织和管理变得至关重要。Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,帮助开发者告别混乱,提升代码质量。
37 1
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
232 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
37 1
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
68 5

热门文章

最新文章