【算法】用递归的方法逆序输出或倒置一个栈

简介: 【算法】用递归的方法逆序输出或倒置一个栈

前言

我们知道,栈是先进先出的,也就是如果一个栈的输入数据为1,2,3,4,5,那么他的输出数据为5,4,3,2,1。

而如果我们想要以队列的方式先进先出一个栈,那么我们就需要用到两个栈,或者,按照标题所说的,我们可以使用递归的方式,来使用一个栈来逆序输出栈中的数据。

两个栈制作一个队列

同时,我们也可以考虑逆序这个栈,也可以做到先进先出的效果。

思路分析

递归函数1:将栈stack的栈底元素移除并且返回。

具体方法如下:

package com.base.learn.stack;
import java.util.Stack;
/**
 * @author: 张锦标
 * @date: 2023/5/27 15:28
 * ReverseStack类
 * 使用递归和栈,来反转输出一个栈
 */
public class ReverseStack {
    private static Stack<Integer> stack = new Stack<>();
    public static int getAndRemoveLastElement(Stack<Integer> stack){
        int result = stack.pop();
        if (stack.isEmpty()){
            return result;
        }else{
            int last = getAndRemoveLastElement(stack);
            stack.push(result);
            return last;
        }
    }
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        System.out.println(getAndRemoveLastElement(stack));
        System.out.println(getAndRemoveLastElement(stack));
        System.out.println(getAndRemoveLastElement(stack));
        System.out.println(getAndRemoveLastElement(stack));
        System.out.println(getAndRemoveLastElement(stack));
    }
}

这里我并不讲解或者画图它是如何做到的,这里建议你直接debug。

递归函数2:逆序一个栈。

我们可以基于递归函数1,递归函数1已经帮我们拿到了最接近栈底的元素了,那么我们只需要拿到这个元素的时候,将其塞入到队列中即可。

代码如下:

package com.base.learn.stack;
import java.util.Stack;
/**
 * @author: 张锦标
 * @date: 2023/5/27 15:28
 * ReverseStack类
 * 使用递归和栈,来反转输出一个栈
 */
public class ReverseStack {
    private static Stack<Integer> stack = new Stack<>();
    public static int getAndRemoveLastElement(Stack<Integer> stack){
        int result = stack.pop();
        if (stack.isEmpty()){
            return result;
        }else{
            int last = getAndRemoveLastElement(stack);
            stack.push(result);
            return last;
        }
    }
    public static void reverse(Stack<Integer> stack){
        if (stack.isEmpty()){
            return ;
        }
        int i = getAndRemoveLastElement(stack);
        System.out.println(i);
        reverse(stack);
        stack.push(i);
    }
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        System.out.println(stack);
        reverse(stack);
        System.out.println(stack);
        //System.out.println(getAndRemoveLastElement(stack));
        //System.out.println(getAndRemoveLastElement(stack));
        //System.out.println(getAndRemoveLastElement(stack));
        //System.out.println(getAndRemoveLastElement(stack));
        //System.out.println(getAndRemoveLastElement(stack));
    }
}

简单讲解

getAndRemoveLastElement方法通过递归的方式,直接访问到了栈的最下层的元素,并且通过递归的方式,出栈这个栈底元素之后,再把其上面的元素再继续压回去,因此做到了不修改栈结构,不使用额外空间的方式来输出栈底元素。

reverse方法则依赖于这个第一个方法,我们知道第一个方法会先输出栈底元素,那么,当reverse方法遍历到最深的时候,其实是得到栈顶元素的时候,因为是逆序的!

所以,当第一个方法递归结束,我们得到的是栈顶的元素,并且第一个方法的每一次调用都会从栈底删除一个元素,那么当第一个方法的递归调用结束的时候,栈以空,那么此时我们拿着栈顶元素,放入到栈中,从而得到逆序栈!


相关文章
|
28天前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
95 4
|
2月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
56 3
|
26天前
|
存储 算法 安全
SnowflakeIdGenerator-雪花算法id生成方法
SnowflakeIdGenerator-雪花算法id生成方法
23 1
|
1月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
52 2
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
86 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
48 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
JSON 算法 数据挖掘
基于图论算法有向图PageRank与无向图Louvain算法构建指令的方式方法 用于支撑qwen agent中的统计相关组件
利用图序列进行数据解读,主要包括节点序列分析、边序列分析以及结合节点和边序列的综合分析。节点序列分析涉及节点度分析(如入度、出度、度中心性)、节点属性分析(如品牌、价格等属性的分布与聚类)、节点标签分析(如不同标签的分布及标签间的关联)。边序列分析则关注边的权重分析(如关联强度)、边的类型分析(如管理、协作等关系)及路径分析(如最短路径计算)。结合节点和边序列的分析,如子图挖掘和图的动态分析,可以帮助深入理解图的结构和功能。例如,通过子图挖掘可以发现具有特定结构的子图,而图的动态分析则能揭示图随时间的变化趋势。这些分析方法结合使用,能够从多个角度全面解读图谱数据,为决策提供有力支持。
|
2月前
|
算法 索引
HashMap扩容时的rehash方法中(e.hash & oldCap) == 0算法推导
HashMap在扩容时,会创建一个新数组,并将旧数组中的数据迁移过去。通过(e.hash & oldCap)是否等于0,数据被巧妙地分为两类:一类保持原有索引位置,另一类索引位置增加旧数组长度。此过程确保了数据均匀分布,提高了查询效率。
48 2
|
2月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
67 3