题目,
给定一个栈,要求只用递归,不额外使用数据结构,将栈反转
分析:
//本题要求用递归,可以用递归的深度遍历,实现最底层返回栈底的元素,然后一层一层向上返回给调用方
//可以用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作为返回值,还不清楚问题出在哪里,