继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

go语言数据结构之栈的实现 栈

勤劳一沙鸥
关注TA
已关注
手记 5
粉丝 8
获赞 18

stack.go

package data_struct

import (
    "fmt"
    "log"
)

//数据结构 栈  先进后出,像电梯

type Stack struct {
    size int64 //容量
    top  int64 //栈顶
    data []interface{}
}

func MakeStack(size int64) Stack {
    q := Stack{}
    q.size = size
    q.data = make([]interface{}, size)
    return q
}

//入栈,栈顶升高
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) Pop() (r interface{}, err error) {
    if t.IsEmpty() {
        err = fmt.Errorf("栈已满,无法完成入栈")
        log.Println("栈已满,无法完成入栈")
        return
    }
    t.top--
    r = t.data[t.top]
    return
}

//栈长度, 已有容量的长度
func (t *Stack) StackLength() int64 {
    return t.top
}

//清空, 不需要清空值 ,再入栈,覆盖即可
func (t *Stack) Clear() {
    t.top = 0
}

//判空
func (t *Stack) IsEmpty() bool {
    return t.top == 0
}

//判满
func (t *Stack) IsFull() bool {
    return t.top == t.size
}

//遍历
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])
        }
    }

}

stack_test.go

package data_struct

import (
    "fmt"
    "testing"
)

func TestNewStack(t *testing.T) {
    s := int64(4)
    q := MakeStack(s)
    if q.size != s {
        t.Error("初始长度%d与创建的栈长度%d不一致", s, q.size)
    }
    if q.top != 0 {
        t.Error("栈顶值不正确,衩始化时,栈顶应为0,实际为%d", q.top)
    }
    if !q.IsEmpty() {
        t.Error("栈应为空,实际为非空")
    }
    if q.IsFull() {
        t.Error("新创建的栈,不应为满")
    }
    if q.StackLength() != 0 {
        t.Error("初始长度应为0,但现在是%d", q.StackLength())
    }
}
func TestStack_Push(t *testing.T) {
    s := int64(4)
    q := MakeStack(s)
    q.Push(10)
    if q.StackLength() != 1 {
        t.Error("长度应为1,但现在是%d", q.StackLength())
    }
    q.Push(12)
    q.Push(14)
    q.Push(16)
    v := q.Push(18)
    if v == true {
        t.Error("满的栈不能再加入,应返回假")
    }
    if q.StackLength() != s {
        t.Error("长度应为%s,但现在是%d", s, q.StackLength())
    }
    q.Clear()
    if q.StackLength() != 0 {
        t.Error("长度应为0,但现在是%d", q.StackLength())
    }
}
func TestStack_Pop(t *testing.T) {
    s := int64(4)
    q := MakeStack(s)
    q.Push(10)
    q.Push(12)
    q.Push(14)
    q.Push(16)
    v, err := q.Pop()
    if err != nil {
        t.Errorf("执行Stack_Pop报错, %s", err)
    }
    if v != 16 {
        t.Errorf("此时栈顶应为16, 但取到的值为%d", v)
    }
    v, err = q.Pop()
    if v != 14 {
        t.Errorf("此时栈顶应为14, 但取到的值为%d", v)
    }
    if q.StackLength() != s-2 {
        t.Errorf("长度应为%d,但现在是%d", s-2, q.StackLength())
    }
}

//测试遍历
func ExampleStack_Traverse() {
    s := int64(4)
    q := MakeStack(s)
    q.Push(10)
    q.Push(12)
    q.Push(14)
    q.Push(16)
    q.Traverse(func(node interface{}) {
        fmt.Println(node)
    }, false)

    q.Pop()
    q.Traverse(func(node interface{}) {
        fmt.Println(node)
    }, true)
    //output:
    //16
    //14
    //12
    //10
    //10
    //12
    //14
}

func ExampleStackDemo1() {

    //栈应用一,十进制转换
    /**
    *   短除法进制转换规则
        N = (N div d)  * d + N mod d    (div ,除, Mod ,求余)
        十进制转8进制
        N       N div 8     N mod 8
        1348    168         4
        168     21          0
        21      2           5
        2       0           2

        N       N div 16    N mod 16
        1348    84          4
        84      5           4
        5       0           5
    *
    **/
    const BINARY int = 2
    const OCTONARY int = 8
    const HEXADECIMAL int = 16

    var fn_c = func(n int, target int) {
        var stack = MakeStack(40)
        for {
            if n == 0 {
                break
            }
            stack.Push(n % target)
            n = n / target
        }
        stack.Traverse(func(node interface{}) {
            fmt.Print(node)
        }, false)
    }

    fn_c(1348, OCTONARY)
    fmt.Println()
    fn_c(1348, HEXADECIMAL)
    fmt.Println()
    fn_c(1348, BINARY)

    //output:
    // 2504
    // 544
    // 10101000100
}
打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP

热门评论

先说问题吧,Pop方法出栈的没有删除栈里面的数据而是直接返回了,不知道是不是故意这样做的,按照栈的定义,应该从 数据中移除。少了Peek和Search方法。我这里给补充了

//获取栈顶对象
func (t *Stack) Peek() (r interface{},err error) {
   if t.IsEmpty() {
      err = fmt.Errorf("")
      log.Printf("栈已空,无法获取栈顶")
      return
   }
   r = t.data[t.top-1]
   return r,err
}

/*
   搜索某一个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
}


查看全部评论