英文:
How to build heap upon custom type
问题
我有一个名为KeyValue的类型,看起来像这样:
type KeyValue struct {
Key string
Value string
}
由于我想在其上构建一个堆,所以我定义了一个ByKey类型,并实现了heap.Interface
接口:
type ByKey []KeyValue
func (a ByKey) Len() int { return len(a) }
func (a ByKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByKey) Less(i, j int) bool { return a[i].Key < a[j].Key }
func (a *ByKey) Push(x interface{}) {
*a = append(*a, x.(KeyValue))
}
func (a *ByKey) Pop() interface{} {
old := *a
n := len(old)
x := old[n-1]
*a = old[0 : n-1]
return x
}
但是当我运行测试时,容器/堆并没有起作用。我的测试代码如下:
dic := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9"}
generate := func(min, max int) *ByKey {
n := rand.Intn(max - min) + min
kvs := make(ByKey, 0)
for i := 0; i < n; i++ {
idx := rand.Intn(len(dic))
kvs = append(kvs, KeyValue{
Key: dic[idx],
Value: "1",
})
}
return &kvs
}
kv1 := generate(10, 15)
fmt.Printf("before heapify kv1: %v\n", *kv1)
heap.Init(kv1)
fmt.Printf("after heapify kv1: %v\n", *kv1)
输出结果为:
before heapify kv1: [{7 1} {3 1} {3 1} {5 1} {7 1} {8 1} {9 1} {5 1} {7 1} {6 1} {8 1}]
after heapify kv1: [{3 1} {5 1} {3 1} {5 1} {6 1} {8 1} {9 1} {7 1} {7 1} {7 1} {8 1}]
不幸的是,kv1
没有按照键值排序。我认为在Swap()
、Push()
或 Pop()
等函数中可能有问题。感谢任何帮助。
英文:
I have a KeyValue type which looks like here:
type KeyValue struct {
Key string
Value string
}
Since I want to build a heap over it, I defined a ByKey type and implements the heap.Interface
interface
type ByKey []KeyValue
func (a ByKey) Len() int { return len(a) }
func (a ByKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByKey) Less(i, j int) bool { return a[i].Key < a[j].Key }
func (a *ByKey) Push(x interface{}) {
*a = append(*a, x.(KeyValue))
}
func (a *ByKey) Pop() interface{} {
old := *a
n := len(old)
x := old[n-1]
*a = old[0 : n-1]
return x
}
But when I run a test, the container/heap does not work. My test code is here:
dic := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9"}
generate := func(min, max int) *ByKey {
n := rand.Intn(max - min) + min
kvs := make(ByKey, 0)
for i := 0; i < n; i++ {
idx := rand.Intn(len(dic))
kvs = append(kvs, KeyValue{
Key: dic[idx],
Value: "1",
})
}
return &kvs
}
kv1 := generate(10, 15)
fmt.Printf("before heapify kv1: %v\n", *kv1)
heap.Init(kv1)
fmt.Printf("after heapify kv1: %v\n", *kv1)
And the output is:
before heapify kv1: [{7 1} {3 1} {3 1} {5 1} {7 1} {8 1} {9 1} {5 1} {7 1} {6 1} {8 1}]
after heapify kv1: [{3 1} {5 1} {3 1} {5 1} {6 1} {8 1} {9 1} {7 1} {7 1} {7 1} {8 1}]
Unfortunately the kv1
is not sorted by key. I think there should be something wrong in functions like Swap()
, Push()
or Pop()
. Any help is appreciated.
答案1
得分: 1
根据文档:
堆是实现优先队列的常见方式。要构建一个优先队列,可以使用(负的)优先级作为Less方法的排序方式来实现Heap接口,因此Push操作会向队列中添加项,而Pop操作会移除队列中优先级最高的项。示例中包含了这样的实现;文件example_pq_test.go包含了完整的源代码。
尝试使用heap.Pop弹出一个值:
for kv1.Len() > 0 {
fmt.Printf("%d ", heap.Pop(kv1))
}
输出结果为:
{3 1}
{3 1}
{5 1}
{5 1}
{6 1}
{7 1}
{7 1}
{7 1}
{8 1}
{8 1}
{9 1}
英文:
According to the docs:
> A heap is a common way to implement a priority queue. To build a priority queue, implement the Heap interface with the (negative) priority as the ordering for the Less method, so Push adds items while Pop removes the highest-priority item from the queue. The Examples include such an implementation; the file example_pq_test.go has the complete source.
Try to heap.Pop a value:
for kv1.Len() > 0 {
fmt.Printf("%d ", heap.Pop(kv1))
}
{3 1}
{3 1}
{5 1}
{5 1}
{6 1}
{7 1}
{7 1}
{7 1}
{8 1}
{8 1}
{9 1}
<kbd>PLAYGROUND</kbd>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论