思路
如果有两个类型相同的栈,我们为它们分别开辟了数组空间。极有可能是一个栈已经满了,再入栈就溢出了,而另一个栈却还有很多存储空间。这又何必呢?我们完全可以用一个数组来存储两个栈,只不过需要一些小的技巧。
我们的做法如下,数组有两个端点,两个栈有两个栈底。让一个栈的栈底为数组的始端,即数组下标为0的位置。让另一个栈的栈底为数组的末端,即数组下标为n-1的位置。这样如果两个栈增加元素,就是两端点向中间延伸。
其实关键思路是:它们是在数组的两端,向中间靠拢。top1和top2是两个栈的栈顶指针。只要它们两个不见面,两个栈就可以一直使用。
实例代码:
package main
import (
"errors"
"fmt"
)
/*
两栈共享数据:通常用在两栈需求相反的情况,如买卖股票,一方买入,一方卖出
*/
type SelemType int
const MaxLen = 6
type SqDoubleStack struct {
data [MaxLen]SelemType
top1 int //栈1的指针
top2 int //栈2的指针
}
/*
fun:栈的初始化操作 设置栈1的指针指向-1;栈2的指针指向 MaxLen(都是指向数组的越界范围)
*/
func InitStack() SqDoubleStack {
var statc SqDoubleStack
statc.top1 = -1
statc.top2 = MaxLen
return statc
}
/*
fun: stackNum:1(栈1添加),2(向栈2进行数据的添加)
*/
func push(s *SqDoubleStack, e SelemType, stackNum int) (err error) {
if s.top1+1 == s.top2 {
err = errors.New("栈已满!")
return
}
if stackNum == 1 {
s.top1++
s.data[s.top1] = e
}
if stackNum == 2 {
s.top2--
s.data[s.top2] = e
}
return
}
func pop(s *SqDoubleStack, stackNum int) (err error, res SelemType) {
//栈1进行的操作
if stackNum == 1 {
if s.top1 == -1 {
err = errors.New("栈1已经为空,不能进行出栈操作")
return
}
res=s.data[s.top1]
s.data[s.top1]=SelemType(0)
s.top1--
}
//栈2进行的操作
if stackNum == 2 {
if s.top2==MaxLen {
err=errors.New("栈2已经为空,不能进行出栈操作")
return
}
res=s.data[s.top2]
s.data[s.top2]=SelemType(0)//数据恢复(清零)
s.top2++
return
}
return
}
func main() {
s:=InitStack()
push(&s,SelemType(888),1)
push(&s,SelemType(666),2)
push(&s,SelemType(11),1)
push(&s,SelemType(22),2)
push(&s,SelemType(90),1)
push(&s,SelemType(44),2)
push(&s,SelemType(33),1)
push(&s,SelemType(33),1)
fmt.Println(s.data)
_,res:=pop(&s,1)
fmt.Println(res)
_,res=pop(&s,1)
fmt.Println(res)
_,res=pop(&s,1)
fmt.Println(res)
err,res:=pop(&s,1)
fmt.Println(err,res)
//显示栈中的数据
fmt.Println(s.data)
}
运行效果: