下面是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. Android 底部导航栏的xml

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&q ...

  2. IDEA创建简单SpringBoot项目

    环境:jdk 1.打开IDEA -->New --> Project -->Spring Initalizer-->next 2.此处,只做创建示例,所以next后Group等 ...

  3. 定时清理elasticsearch

    索引这种格式 以下脚本加入crontab #每天清理es数据 0 1 * * * /data/sh/rm_esindex.sh >> /data/logs/crontab/rm_esind ...

  4. linux下安装jdk 详细步骤(一条命令即可安装)

    转载:https://blog.csdn.net/luochangchen/article/details/72804426 作为Java开发人员,在Linux下安装一些开发工具是必备技能,本文以安装 ...

  5. silverlight 基本信息学习随笔

    Silverlight还处于测试版本阶段 微软 silverlight 是一个跨浏览器.跨平台的插件.为网络带来下一代基于.NETFramework的媒体体验和丰富的交互式应用程序 他是一种新的web ...

  6. Flask 上下文管理

    为什么用threading.local? 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程 ...

  7. 09_java基础——this

    多次调用同一个对象的某个方法: package com.huawei.test.java04; /** * This is Description * * @author 王明飞 * @date 20 ...

  8. flashback_scn导出

    1.应用场景2.oracle实现该技术的原理理论,及限制3.实操及与scn时间相关的函数查询 一.flashback_scn导出1) OGG同步,对表的数据进行同步,第一次可以完全导出,中途如果由于某 ...

  9. Pytorch 报错总结

    目前在学习pytorch,自己写了一些例子,在这里记录下来一些报错及总结 1. RuntimeError: Expected object of type torch.FloatTensor but ...

  10. leetcode 刷题(3)--- 无重复字符的最长子串

    给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc",其长度为 ...