在Go中实现堆栈以便存储结构的正确方法是什么?

Ino*_*dle 2 stack types go

我正在尝试制作一个存储一系列霍夫曼树结构的堆栈.目前我正在使用我在github上找到的实现.

package util

type item struct {
    value interface{}
    next  *item
}

//Stack the implementation of stack
//this stack is not thread safe!
type Stack struct {
    top  *item
    size int
}
// Basic stack methods...
Run Code Online (Sandbox Code Playgroud)

问题是当我将我的霍夫曼树结构存储在堆栈中时,我不能使用霍夫曼树的任何字段,例如左/右子.

package huffmantree

type HuffmanTree struct {
    freq   int
    value  byte
    isLeaf bool
    left   *HuffmanTree
    right  *HuffmanTree
    code   []bool
    depth  int
}
Run Code Online (Sandbox Code Playgroud)

我怎么能在Go中实现一个堆栈,它将正确存储结构并允许访问它们的字段?

编辑:我尝试用(huffmantree结构)替换该interface {}部分huffmantree.HuffmanTree并得到此错误消息:

can't load package: import cycle not allowed
package github.com/inondle/huffman/util
    imports github.com/inondle/huffman/huffmantree
    imports github.com/inondle/huffman/util
import cycle not allowed
Run Code Online (Sandbox Code Playgroud)

我的猜测是huffmantree类导入了util包,而堆栈必须导入huffmantree包,所以存在某种冲突?谁知道出了什么问题?

Pau*_*kin 6

实现堆栈的正确方法就是使用切片.

stack := []*HuffmanTree{}
Run Code Online (Sandbox Code Playgroud)

您可以使用append,然后通过写入弹出到堆栈:

v, stack := stack[len(stack)-1], stack[:len(stack)-1]
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以将其封装到自己的类型中,但切片更容易理解.

type Stack []*HuffmanTree{}

func NewStack() *Stack {
    var s []*HuffmanTree
    return (*Stack)(&s)
}

func (s *Stack) Pop() *HuffmanTree {
    v = (*s)[len(*s)-1]
    *s = (*s)[:len(*s)-1]
    return v
}

func (s *Stack) Push(h *HuffmanTree) {
    *s = append(*s, h)
}
Run Code Online (Sandbox Code Playgroud)

正如icza观察到的,如果堆栈的生存时间比HuffmanTree对象长,那么您可能希望将堆栈中刚刚弹出的条目归零,以允许垃圾收集器收集未引用的对象.

  • 请注意,从切片堆栈弹出元素也应该用零值填充弹出元素的空间,因为底层数组仍将保留该值并阻止垃圾回收器回收其内存.对于原始值类型(例如`int`)而言,归零是不行的,但对于指针,映射,切片或具有指针字段等的结构也不行. (2认同)