设计一个有getMin功能的栈(go 语言版本)

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

栈的实现借助于g o语言数据结构之栈的实现 栈 慕课网大佬文章参考,并在上面完善功能

模拟栈的方法如下

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]
    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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Java byte code 的学习意义 为啥要学java bytecode,这就跟你问我已经会python了为...
    shanggl阅读 1,866评论 0 3
  • 笔记 CSS 一、css简述 1、css是什么 ? 有什么作用 HTML--页面结构,人的面部 CSS--美化页...
    烂漫的点地梅阅读 133评论 0 0
  • 一、健康 1、早起目标:5:00 早睡目标:22:30 完成情况:平均早起5:02,平均睡眠时间05时21分 平均...
    六安姐阅读 334评论 0 1
  • 一、定时器 1、循环定时器的设置和取消 (1)启动循环定时器:setlnterval() 循环定时器,调...
    烂漫的点地梅阅读 153评论 0 0
  • 0x1 WAF的常见特征 之所以要谈到WAF的常见特征,是为了更好的了解WAF的运行机制,这样就能增加几分绕过的机...
    土拨鼠先生_阅读 832评论 0 0

友情链接更多精彩内容