为了账号安全,请及时绑定邮箱和手机立即绑定

Go语言 设计一个有getMin功能的栈

标签:
Go 算法

一、go语言 栈的实现 代码如下

栈的实现借助于下面原文的作者提供链接如下,并在上面完善功能
go语言数据结构之栈的实现 栈

模拟栈的方法如下

InitStack 初始化栈
StackLength 获取栈的长度
IsEmpty 判断是否为空
IsFull 判断是否已经满了
Clear 清空栈
Peek 获取栈顶对象
Search
Pop 出栈
Push 入栈
Traverse 遍历栈

package MyStack
import (
	"fmt"
	"log"
	"reflect"
)
type Stack struct {
	size int64 //容量
	top  int64 //栈顶
	data []interface{}
}
//初始化栈
func InitStack(size int64) Stack {
	t := Stack{}
	t.size = size
	t.data = make([]interface{}, size)
	return t
}
//出栈,栈顶下降
func (t *Stack) Pop() (r interface{}, err error) {
	if t.IsEmpty() {
		err = fmt.Errorf("栈已空,无法完成出栈")
		log.Printf("栈已空,无法完成出栈")
		return
	}
	t.top--
	r = t.data[t.top]
	t.data = t.data[:t.top]
	return
}
//入栈,栈顶升高
func (t *Stack) Push(element interface{}) bool {
	if t.IsFull() {
		log.Printf("栈已满,无法完成入栈")
		return false
	}
	t.data[t.top] = element
	t.top++
	return true
}
//遍历栈
func (t *Stack) Traverse(fn func(node interface{}), isTop2Bottom bool) {
	if isTop2Bottom {
		var i int64 = 0
		for ; i < t.top; i++ {
			fn(t.data[i])
		}
	} else {
		for i := t.top - 1; i >= 0; i-- {
			fn(t.data[i])
		}
	}
}
//栈的长度
func (t *Stack) StackLength() int64 {
	return t.top
}
//检查栈是否为空
func (t *Stack) IsEmpty() bool {
	return t.top == 0
}
//清空栈
func (t *Stack) Clear() {
	t.top = 0
}
//判断是否已满
func (t *Stack) IsFull() bool {
	return t.size == t.top
}
//获取栈顶对象
func (t *Stack) Peek() (r interface{}, err error) {
	if t.IsEmpty() {
		err = fmt.Errorf("")
		log.Printf("栈已空,无法获取栈顶")
		return
	}
	r = t.data[t.top-1]
	return
}
/*
	搜索某一个item在该栈中的位置【位置为离栈顶最近的item与栈顶间距离】
	方法调用返回从堆栈中,对象位于顶部的基于1的位置。
*/
func (t *Stack) Search(r interface{}) (post int64, err error) {
	post = int64(0)
	if t.IsEmpty() {
		err = fmt.Errorf("")
		log.Printf("栈已空,无法获取栈顶")
		return
	}

	for k, v := range t.data {
		fmt.Println(k, v)
		if reflect.DeepEqual(v, r) {
			post = int64(t.top) - int64(k)
		}
	}
	return
}

二、getMin功能的栈实现设计方案如下

方案一、 压入数据规则
压入规则:​
假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空:​ 如果为空,则newNum也压入stackMin。​如果不为空,则比较newNum和stackMin的栈顶元素哪一个更小:如果newNum更小或两者相等,newNum也压入stackMin;​如果stackMin中栈顶元素小,则stackMin不压入任何内容。
//MyStack1.go文件
package MyStack
//方案一、 压入数据规则,获取最小值
import (
	"fmt"
	"log"
)

type MyStack1 struct {
	stackData Stack
	stackMin Stack
}

//初始化结构体数值
func InitStackData(size int64) MyStack1 {
	t := MyStack1{}
	t.stackData = InitStack(size)
	t.stackMin = InitStack(size)
	return t
}
func (t *MyStack1) Push(newNum interface{}) {
	if t.stackMin.IsEmpty() {
		t.stackMin.Push(newNum)
	} else if v := t.GetMin();v.(int) >= newNum.(int) {
		t.stackMin.Push(newNum)
	}
	t.stackData.Push(newNum)
}
func (t *MyStack1) Pop() (r interface{}) {
	if t.stackData.IsEmpty() {
		fmt.Errorf("stackData is empty")
		log.Print("stackData is empty")
		return
	}
	r,_ = t.stackData.Pop()
	if r== t.GetMin() {
		t.stackMin.Pop()
	}
	return
}
func (t *MyStack1) GetMin() (r interface{}) {
	 if t.stackMin.IsEmpty() {
	 	 fmt.Errorf("stackMin is empty")
	 	 log.Print("stackMin is empty")
	 	 return
	 }
	 r,_ = t.stackMin.Peek()
	 return r
}
//main.go文件

/**
作者:black
日期: 2020年03月22日
说明文档:设计一个特殊功能的栈 getMin
*/
package main
import (
	"MyStack"
	"fmt"
)
func main()  {
	size := int64(10)
	//方案 一、压入数据规则
	fmt.Println("方案1:压入数据规则")
	MyStack1 := MyStack.InitStackData(size);
	MyStack1.Push(10)
	MyStack1.Push(3)
	MyStack1.Push(13)
	MyStack1.Push(10)
	MyStack1.Push(14)
	MyStack1.Push(6)
	MyStack1.Push(433)
	fmt.Println("方案1:压入数据规则最小值",MyStack1.GetMin())

	//方案 二、弹出数据规则
	fmt.Println("方案2:弹出数据规则")
	MyStack2 := MyStack.InitStackData2(size);
	MyStack2.Push(10)
	MyStack2.Push(3)
	MyStack2.Push(13)
	MyStack2.Push(10)
	MyStack2.Push(14)
	MyStack2.Push(6)
	MyStack2.Push(433)
	fmt.Println("方案2:压入数据规则最小值",MyStack2.GetMin())
}

方案二、 弹出数据规则
弹出规则:​
当入栈的时候,如果stackMin是空,则入栈stackMin,当再此入栈,stackMin栈顶数值val和入栈的数值newval做比较,如果val>newval,那么stackMin就入栈newval到stackMin,如果val<= newval,就拿到stackMin栈顶的值入到stackMin里面
package MyStack
//方案一、 压入数据规则,获取最小值
import (
	"fmt"
	"log"
)

type MyStack2 struct {
	stackData Stack
	stackMin Stack
}

//初始化结构体数值
func InitStackData2(size int64) MyStack2 {
	t := MyStack2{}
	t.stackData = InitStack(size)
	t.stackMin = InitStack(size)
	return t
}

func (t *MyStack2) Push(r interface{}) {
	if t.stackMin.IsEmpty() {
		t.stackMin.Push(r)
	} else if v := t.GetMin();v.(int) > r.(int) {
		t.stackMin.Push(r)
	} else { // v<=r
		r1,_ := t.stackMin.Peek()
		t.stackMin.Push(r1)
	}
	t.stackData.Push(r)
}

func (t *MyStack2) Pop() (r interface{}) {
	if t.stackData.IsEmpty() {
		fmt.Errorf("stackData is empty")
		log.Print("stackData is empty")
		return
	}
	t.stackMin.Pop()
	r,_ = t.stackData.Pop()
	return
}

func (t *MyStack2) GetMin() (r interface{}) {
	 if t.stackMin.IsEmpty() {
	 	 fmt.Errorf("stackMin is empty")
	 	 log.Print("stackMin is empty")
	 	 return
	 }
	 r,_ = t.stackMin.Peek()
	 return r
}
点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消