下面是golang实现的简单优先队列,参考信息可以查看https://golang.org/pkg/container/heap/或者https://golang.google.cn/pkg/container/heap/,后面这个网址也是官方提供的网址,关于这个网页的说明,可以参考https://blog.golang.org/hello-china。

package queue

import "container/heap"

// QItem 表示存储到这个队列中需要实现的接口
type QItem interface {
Less(item QItem) bool
} // priorityQueueImpl 用于优先队列底层实现
type priorityQueueImpl []QItem // Len 获取队列长度
func (pqi priorityQueueImpl) Len() int {
return len(pqi)
} // Less 用来进行元素比较
func (pqi priorityQueueImpl) Less(i, j int) bool {
return pqi[i].Less(pqi[j])
} // Swap 进行交换
func (pqi priorityQueueImpl) Swap(i, j int) {
pqi[i], pqi[j] = pqi[j], pqi[i]
} // Push 用来将一个对象压入队列中
func (pqi *priorityQueueImpl) Push(x interface{}) {
item := x.(QItem)
*pqi = append(*pqi, item)
} // Pop 将一个对象弹出队列
func (pqi *priorityQueueImpl) Pop() interface{} {
old := *pqi
n := len(old)
item := old[n-1]
*pqi = old[0 : n-1]
return item
} // PriorityQueue 实现优先队列
type PriorityQueue struct {
priorityQueueImpl
} // NewPriorityQueue 用来构建PriorityQueue
func NewPriorityQueue() *PriorityQueue {
var pq PriorityQueue
heap.Init(&pq.priorityQueueImpl)
return &pq
} // Push 用来将一个对象压入到队列中
func (pq *PriorityQueue) Push(item QItem) {
heap.Push(&pq.priorityQueueImpl, item)
} // Pop 用来从队列中弹出一个对象
func (pq *PriorityQueue) Pop() QItem {
return heap.Pop(&pq.priorityQueueImpl).(QItem)
} // Front 用来获取当前队列中的最小值
func (pq *PriorityQueue) Front() QItem {
// 队列中第一位应该就是最小值
return pq.priorityQueueImpl[0]
} // Length 用来获取当前队列的长度
func (pq *PriorityQueue) Length() int {
return pq.priorityQueueImpl.Len()
}

如果希望一个结构可以存储到PriorityQueue中,需要实现QItem接口中的函数,即Less函数。下面给出一个简单的示例:

type Int int

func (i Int) Less(j QItem) bool {
return i < j.(Int)
}

注意func (i Int) Less(j QItem) bool中的传参是QItem,而不是Int,golang当前还不支持泛型,所以,如果想要实现C++的STL的那种效果,应该是不可能的,就算使用反射来使得更多的类型得到支持,也势必会带来很大的性能开销,这个是我不太乐见的。关于将Int类型作为参数进行使用,可以参考下面的测试代码,这个测试代码不太规范,不过测试效果应该可以实现:

func Test_NewPriorityQueue(t *testing.T) {
pq := NewPriorityQueue()
pq.Push(Int(5))
pq.Push(Int(8))
pq.Push(Int(3)) first := pq.Front()
if first != Int(3) {
t.Error("first should be 3")
return
} first = pq.Pop()
if first != Int(3) {
t.Error("first should be 3")
return
} second := pq.Pop()
if second != Int(5) {
t.Error("second should be 5")
return
} pq.Push(Int(1))
length := pq.Length()
if length != 2 {
t.Error("length should be 2")
return
} third := pq.Front()
if third != Int(1) {
t.Error("third should be 1")
return
} third = pq.Pop()
if third != Int(1) {
t.Error("third should be 1")
return
} fourth := pq.Pop()
if fourth != Int(8) {
t.Error("fourth should be 8")
return
} length = pq.Length()
if length != 0 {
t.Error("empty length should be 0")
return
}
}

在实际使用中,可能需要对func (pq *PriorityQueue) Pop() QItem函数和func (pq *PriorityQueue) Front() QItem函数获得的值进行类型强转,使用起来更像是面向对象程序设计的那种方式了。对于需要动态修改优先队列中成员值的情况,可以参考实现。

golang实现的简单优先队列的更多相关文章

  1. 数据结构和算法(Golang实现)(1)简单入门Golang-前言

    数据结构和算法在计算机科学里,有非常重要的地位.此系列文章尝试使用 Golang 编程语言来实现各种数据结构和算法,并且适当进行算法分析. 我们会先简单学习一下Golang,然后进入计算机程序世界的第 ...

  2. 数据结构和算法(Golang实现)(2)简单入门Golang-包、变量和函数

    包.变量和函数 一.举个例子 现在我们来建立一个完整的程序main.go: // Golang程序入口的包名必须为 main package main // import "golang&q ...

  3. 数据结构和算法(Golang实现)(3)简单入门Golang-流程控制语句

    流程控制语句 计算机编程语言中,流程控制语句很重要,可以让机器知道什么时候做什么事,做几次.主要有条件和循环语句. Golang只有一种循环:for,只有一种判断:if,还有一种特殊的switch条件 ...

  4. 数据结构和算法(Golang实现)(4)简单入门Golang-结构体和方法

    结构体和方法 一.值,指针和引用 我们现在有一段程序: package main import "fmt" func main() { // a,b 是一个值 a := 5 b : ...

  5. 数据结构和算法(Golang实现)(5)简单入门Golang-接口

    接口 在Golang世界中,有一种叫interface的东西,很是神奇. 一.数据类型 interface{} 如果你事前并不知道变量是哪种数据类型,不知道它是整数还是字符串,但是你还是想要使用它. ...

  6. 数据结构和算法(Golang实现)(6)简单入门Golang-并发、协程和信道

    并发.协程和信道 Golang语言提供了go关键字,以及名为chan的数据类型,以及一些标准库的并发锁等,我们将会简单介绍一下并发的一些概念,然后学习这些Golang特征知识. 一.并发介绍 我们写程 ...

  7. 数据结构和算法(Golang实现)(7)简单入门Golang-标准库

    使用标准库 一.避免重复造轮子 官方提供了很多库给我们用,是封装好的轮子,比如包fmt,我们多次使用它来打印数据. 我们可以查看到其里面的实现: package fmt func Println(a ...

  8. TODO:Golang UDP连接简单测试慎用Deadline

    TODO:Golang UDP连接简单测试慎用Deadline UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interco ...

  9. Golang+chromedp+goquery 简单爬取动态数据

    目录 Golang+chromedp+goquery 简单爬取动态数据 Golang的安装 下载golang软件 解压golang 配置golang 重新导入配置 chromedp框架的使用 实际的代 ...

随机推荐

  1. python 2.7和3.7都支持的情况 bit_length() pycharm 更改解释器

    1.头部加: #!/usr/bin/env python # -*- coding:utf-8 -*-    2.bit_length() :当前数值为二进制时,至少要用多少为表示 a = 5 b = ...

  2. VIM:Found a swap file by the name

    在linux下用vi或vim打开Test.java文件时 [root@localhost tmp]# vi Test.java出现了如下信息: E325: ATTENTION    Found a s ...

  3. 远程过程调用发展历程 WebAPI GRPC Hprose

    作者:马秉尧链接:https://www.zhihu.com/question/23299132/answer/109978084来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  4. MongoDB慢查询性能分析

    最近,长期运营后的港台服出现一个问题,web充值很慢,用gm指令查询玩家信息也很慢.最后定位到MongoDB查询也很慢.   刚开始定位的时候,运营SA直接查指定的玩家,并反映很慢,就猜测是索引的问题 ...

  5. JavaScript中易混淆的DOM属性及方法对比

    JavaScript中易混淆的DOM属性及方法对比 ParentNode.children VS Node.prototype.childNodes ParentNode.children:该属性继承 ...

  6. Spring-AOP 基于注解的实现

    一.AOP: 是对OOP编程方式的一种补充.翻译过来为“面向切面编程”. 可以理解为一个拦截器框架,但是这个拦截器会非常武断,如果它拦截一个类,那么它就会拦截这个类中的所有方法.如对一个目标列的代理, ...

  7. adb+monkey压力测试入门

    一.ADB安装步骤及ADB环境配置 1.ADB安装步骤 1)adb工具安装地址:http://www.wmzhe.com/soft-39913.html 2)下载安装包后,解压,将adb安装在根目录下 ...

  8. VMware 虚拟机安装-->wrf、cmaq安装

    微信关注公众号 “软件安装管家” 下载并安装VMware 下面简要记载我的安装和设置步骤: 下载解压,右键以管理员方式运行 安装好了之后 双击桌面 的VMware 输入许可证密钥:AA510-2DF1 ...

  9. mysql count 主键之坑

    https://www.2cto.com/database/201508/433975.html

  10. mysql安装杂记

    绿色版安装 先进入bin目录下初始化 命令:mysqld -initialize-insecure    mysqld --initialize --user=mysql --console    初 ...