下面是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. vue项目中如何使用less

    首先你的vue-cli下载完成 第一步   安装less-loader  依赖 npm  install  less less-loader  --save-dev 直接自动就配置上了,不用手动配置 ...

  2. kettle 在javascrip代码组件中使用fireToDB()函数实现自定义数据库查询

    kettele里面的demo如下; var strConn = "MY Connection";var strSQL = "SELECT COUNT(*) FROM .. ...

  3. python智能提示配置

    Package Control 安装方法 1.通过快捷键 ctrl+` 或者 View > Show Console 打开控制台,然后粘贴相应的 Python 安装代码: 2.Sublime T ...

  4. int 和 Integer

    现状1+1=?,不加思索2.有一个数字要存储在程序里,不加思索int.那为什么java要弄一个Integer类型出来?有什么用?怎么用?差别在哪儿?度娘说java提供了两种数据类型,一种是值类型,一种 ...

  5. thinkphp5.0如何隐藏index.php入口文件

    隐藏入口文件 public/index.php 同级的.htaccess文件 [ Apache ] 方法1: <IfModule mod_rewrite.c> Options +Follo ...

  6. MongoDB慢查询性能分析

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

  7. C语言权威指南和书单 - 中等级别

    注:点击标题免费下载电子书 1. Object-oriented Programming with ANSI-C 2. C Interfaces and Implementations 3. 21st ...

  8. vue-cli搭建项目模拟后台接口数据,webpack-dev-conf.js文件配置

    webpack.dev.conf.js 首先第一步 const express = require('express');const app = express();var appData = req ...

  9. 新 radio样式修改

    https://blog.csdn.net/qq_41617704/article/details/80973966

  10. NSURLConnectionDataDelegate

    #pragma mark-NSURLConnectionDataDelegate //收到回应 - (void)connection:(NSURLConnection *)connection did ...