算法52-用递归反转栈中元素

题目,
给定一个栈,要求只用递归,不额外使用数据结构,将栈反转

分析:

//本题要求用递归,可以用递归的深度遍历,实现最底层返回栈底的元素,然后一层一层向上返回给调用方
//可以用pop和push的时机配合,实现取出最底层的元素,再把上面的数据按照原有顺序压入栈,实现只取栈底,其他不动
//每一层都先拿到当前的栈顶,等待递归返回栈底数据后,最深层先入栈,在一层一层网上入栈,这样原始的顺序不变,只是取出了最底层的元素
//从下往上一层一层的将自己拿到的栈顶的数压入栈,这样就相当于弹出了栈底的元素,然后每个元素向下降一层

getbutton()逻辑:
在这里插入图片描述
reverse()
在这里插入图片描述

代码:

package main

import (
	"fmt"
	"errors"
)

type Stack []int

// 入栈
func (s *Stack) push(a int) {
	*s = append(*s, a)
}
func (s *Stack) isempty()bool{
	if len(*s)>0{
		return false
	}else{
		return true
	}
}
// 出栈
func (s *Stack) pop() (int, error) {
	if (len(*s) == 0) {
		return 0, errors.New("Empty Stack")
	}
	a := *s
	defer func() {
		*s = a[:len(a) - 1]
	}()
	return a[len(a) - 1], nil
}
//本题要求用递归,可以用递归的深度遍历,最底层返回栈底的数,一层一层向上返回
//用pop和push的时机配合,实现取出最底层,再把上面的数据按照原有顺序压入栈,实现只取栈底,其他不动
//每一层都先拿到当前的栈顶,等待递归返回栈底
//从下往上一层一层的将自己拿到的栈顶的数压入栈,这样就相当于弹出了栈底的元素,然后每个元素向下降一层
func getbutton(s Stack) (int,Stack){
	tmp,_:=s.pop()
	fmt.Printf("pop %v\n",tmp)

	//如果栈空了,那么tmp就是最后一个元素,返回
	if s.isempty() {
		fmt.Printf("空了    %v\n",tmp)
		fmt.Printf("空了    %p\n",s)

		return tmp,s
		//没空我就先存着,再给我向下去取,等取回来的时候我把存着的入栈
		//空了就什么都不做,把取到的的给上层
	} else {//如果没空就继续向下去取
		var result int
		result,s=getbutton(s)
		fmt.Printf("return %v\n",result)
		fmt.Printf("puash %v\n",tmp)
		s.push(tmp)//把不是栈底的数压入栈
		return result,s	
	}
}
func reverse(s Stack)Stack {
	if s.isempty() {
		return s
	} else {
		i,s:=getbutton(s)
		fmt.Printf("ssss%v\n",s)
		reverse(s)
		fmt.Printf("  reverse   push %v\n",i)

		s.push(i)
		return s
	}
}
func main(){
	// n:=5
	var s Stack = []int{}
	for i:=3;i>0;i--{
		s.push(i)
	}
	fmt.Println(s)
	s=reverse(s)
	fmt.Printf(" %p\n",s )

	fmt.Println(s)
}

总结:
1 栈的s传入给了函数,但最后在主函数打印的s的元素并没有变化,查看每个函数中的s的地址,的确都是同一个,最后只能将改为将s作为返回值,还不清楚问题出在哪里,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值