当前位置: 首页 > news >正文

golang 使用双向链表作为container/heap的载体

MyHeap:container/heap的数据载体,需要实现以下方法:

Len:堆中数据个数

Less:第i个元素 是否必 第j个元素 值小

Swap:交换第i个元素和 第j个元素

Push:向堆中追加元素

Pop:从堆中取出元素

下面是使用双向链路作为数据载体的最小堆实现方式:

package mainimport ("container/heap""fmt"
)type HeapItem struct {Value intPrev  *HeapItemNext  *HeapItem
}type MyHeap struct {Head   *HeapItemTail   *HeapItemLength int
}func (h *MyHeap) Len() int {return h.Length
}func (h *MyHeap) Less(i, j int) bool {return h.Find(i).Value < h.Find(j).Value
}func (h *MyHeap) Swap(i, j int) {nodeI, nodeJ := h.Find(i), h.Find(j)isNear := h.IsNear(nodeI, nodeJ)// 记录I的前和后nodeIPrev, nodeINext := nodeI.Prev, nodeI.Next// 记录J的前和后nodeJPrev, nodeJNext := nodeJ.Prev, nodeJ.Next// 把J放到I的位置nodeIPrev.Next = nodeJnodeJ.Prev = nodeIPrevnodeJ.Next = nodeINext // near, 对于相邻元素, 这样操作有问题, 下面会重新赋值nodeINext.Prev = nodeJ // near, 对于相邻元素, 这样操作有问题, 下面会重新赋值// 把I放到J的位置nodeJPrev.Next = nodeI // near, 对于相邻元素, 这样操作有问题, 下面会重新赋值nodeI.Prev = nodeJPrev // near, 对于相邻元素, 这样操作有问题, 下面会重新赋值nodeI.Next = nodeJNextnodeJNext.Prev = nodeI// 对于相邻元素,重新赋值if isNear {nodeJ.Next = nodeInodeINext.Prev = nodeIPrevnodeJPrev.Next = nodeJNextnodeI.Prev = nodeJ}
}func (h *MyHeap) Push(v interface{}) {newItem := v.(*HeapItem)temp := h.Tail.Prevtemp.Next = newItemnewItem.Prev = tempnewItem.Next = h.Tailh.Tail.Prev = newItemh.Length++return
}func (h *MyHeap) Pop() interface{} {realTailNode := h.Tail.PrevrealTailNode.Prev.Next = realTailNode.NextrealTailNode.Next.Prev = realTailNode.Prevh.Length--return realTailNode
}func (h *MyHeap) IsNear(nodeI, nodeJ *HeapItem) bool {if nodeI.Next == nodeJ {return true}return false
}func (h *MyHeap) Find(i int) *HeapItem {nodeI := h.Headfor k := 0; k <= i; k++ {nodeI = nodeI.Next}return nodeI
}func (h *MyHeap) Show() {forward := ""backward := ""i := 0for curr := h.Head; curr != nil && i < 10; curr = curr.Next {forward += fmt.Sprintf("'%d'->", curr.Value)i++}j := 0for curr := h.Tail; curr != nil && j < 10; curr = curr.Prev {backward = fmt.Sprintf("'%d'<-", curr.Value) + backwardj++}fmt.Printf("forward=%s, backward=%s\n", forward, backward)
}func InitHeap() *MyHeap {head := &HeapItem{Value: -1}tail := &HeapItem{Value: -2}head.Next = tailtail.Prev = headreturn &MyHeap{Head:   head,Tail:   tail,Length: 0,}
}func main() {myHeap := InitHeap()heap.Init(myHeap)heap.Push(myHeap, &HeapItem{Value: 10})heap.Push(myHeap, &HeapItem{Value: 1000})heap.Push(myHeap, &HeapItem{Value: 5})heap.Push(myHeap, &HeapItem{Value: 1})heap.Push(myHeap, &HeapItem{Value: 7})myHeap.Show()for myHeap.Len() > 0 {item := heap.Pop(myHeap).(*HeapItem)fmt.Printf("%d ", item.Value)}fmt.Println()
}

http://www.lryc.cn/news/526070.html

相关文章:

  • C#集合操作优化:高效实现批量添加与删除
  • 142.WEB渗透测试-信息收集-小程序、app(13)
  • 24.日常算法
  • 分布式理解
  • wordpress调用指定ID页面的链接
  • 单值二叉树(C语言详解版)
  • python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加
  • 速通Docker === Docker Compose
  • LMI Gocator GO_SDK VS2019引用配置
  • 技术之翼,创作之心
  • WebSocket异步导出
  • OS2.【Linux】基本命令入门(1)
  • 【二叉树】4. 判断一颗二叉树是否是平衡二叉树。5. 对称二叉树。6. 二叉树的构建及遍历 7. 二叉树的分层遍历 。
  • OS Copilot功能测评:智能助手的炫彩魔法
  • MFC结构体数据文件读写实例
  • 音频 PCM 格式 - raw data
  • 关于deepin上运行Qt开发的程序
  • css 如何将字体进行压扁,即水平缩放scaleX
  • C++AVL树(二)详解
  • RocketMQ 的 Topic 和消息队列MessageQueue信息,是怎么分布到Broker的?怎么负载均衡到Broker的?
  • 无人机核心项目开发系列:从设计到实现的完整解析
  • 浅谈Redis
  • Ceisum无人机巡检直播视频投射
  • 【组件库】使用Vue2+AntV X6+ElementUI 实现拖拽配置自定义vue节点
  • Vue.js组件开发-如何实现全选反选
  • 2025.1.20——四、[强网杯 2019]Upload1 文件上传|反序列化
  • php代码审计2 piwigo CMS in_array()函数漏洞
  • docker搭建redis集群(三主三从)
  • [Datawheel]利用Zigent框架编写智能体-1
  • 【计算机视觉】人脸识别