递归实现反转栈Java

烧脑提醒!烧脑提醒!烧脑提醒!在这里插入图片描述
不皮了,下面开始正题。

题目要求:用递归实现栈反转。

我走的弯路:
首先,我刚开始的想法,我觉得,递归其实本质也是个栈类型的数据结构,所以可以利用递归过程的栈来实现反转。其实,这个思路有问题,因为你递归的过程中,其实也是在出栈操作,当你递归到栈底时,此时,递归函数中最后一个值也是栈底元素,此时,再入栈,其实又原路返回了,所以,必须在此基础上,再递归一次,我看到网上有这种解法,太恶心了,两个递归嵌套。其实这种解法并不是此题的本意,此题的本意是考查对递归思想的深入理解。

我的解法:
这道题其实根源考查的是对递归思想的理解。首先,递归过程最难理解的地方就是,当你递归到出口,然后开始向上反推的过程中,其实,是可以直接用从递归出口反推过来的结果的。
相当于,递归就是一个把问题不断缩小的过程,当问题缩小到某个程度时,可以解决了,解决掉这个最小问题,然后开始向上反推,因此,在这个反推的过程中,所有返回的结果,都可以理解为前面的问题已经解决了,因此就可以直接使用下一层的递归结果。
例如:在本题中,reverseStack()方法是用来反转栈的,所以我们在递归向上回推得过程中,可以理解为,每个reverseStack()都是已经反转好的栈。因此,可以直接使用下一层反转后的结果。
下面举例说明具体步骤:
入栈:12345678
1.出栈栈顶元素8,用temp1保存。
2.递归调用反转函数reverseStack(注意,此时,就像前面说的那样,当递归回推到这一步时,默认下面的功能已经实现,因此,反转后栈为7654321,栈顶为1
3.出栈栈顶元素1.用temp2保存。
4.递归调用反转函数reverseStack(此时反转后结果为234567,7是栈顶)
5.把temp1=8入栈(此时栈为2345678,8是栈顶)
6.再次调用反转函数reverseStack(结果为8765432,2为栈顶)
7.把temp2入栈(此时栈为87654321)
到此时,一次递归反转完成了,做了什么事呢?相当于,取出第一个和最后一个数,然后递归,当真正只剩一个数时,相当于这个数不用反转就反转成功了,因为一个数的反转还是它本身,此时,向上递推,把之前保存的头尾依次加上。

下面是代码:

public static void main(String[] args) {
		Stack<Integer> s=new Stack<Integer>();
		s.push(1);
		s.push(2);
		s.push(3);
		s.push(4);
		reverseStack(s);
		System.out.println(s.pop());
		System.out.println(s.pop());
		System.out.println(s.pop());
		System.out.println(s.pop());
	}
	public static void reverseStack(Stack<Integer> s) {
		//当栈等于1或者小于1时,返回,因为一个数反转后还是它本身
		if(s.size()<=1) {
			return;
		}
		int temp1=s.pop();
		reverseStack(s);
		int temp2=s.pop();
		reverseStack(s);
		s.push(temp1);
		reverseStack(s);
		s.push(temp2);
	}

代码很简单,就几行而已,但是这个递归的思想是最难理解的。相当于,我们只需要简单考虑第一次反转怎么解决就可以了,默认使用后面的反转成果,当栈中元素只剩下一个时,一个元素它本身就符合反转成果了,因此就可以向上反推,用最小的反转成果,逐个解决上层反转。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值