Go语言 大话数据结构——两栈共享空间

思路
  如果有两个类型相同的栈,我们为它们分别开辟了数组空间。极有可能是一个栈已经满了,再入栈就溢出了,而另一个栈却还有很多存储空间。这又何必呢?我们完全可以用一个数组来存储两个栈,只不过需要一些小的技巧。
  我们的做法如下,数组有两个端点,两个栈有两个栈底。让一个栈的栈底为数组的始端,即数组下标为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)

}

运行效果:

猜你喜欢

转载自blog.csdn.net/weixin_42117918/article/details/81839296