golang 标准库 container/ring 及 container/heap

由于目前golang 没有提供泛型机制,所以通用容器实现基本和 c 类似,golang 用 interface{} 做转接, c 用 void * 转接。

ring 包实现循环双向链表:

type Ring struct   {    
   next, prev *Ring    
   Value      interface{} 
}

内部导出一个用户可以操作的Value 字段。

heap 包实现 binary heap :

type Interface interface {        
     sort.Interface
     Push(x interface{}) // add x as element Len()
     Pop() interface{}   // remove and return element Len() - 1.
}

heap.Interface 内嵌 sort.Interface, 提供了接口组合的好例子,只要客户的数据类型实现这五个方法,即可插入binary heap  中,进行相关操作(排序,优先队列等)。

package main

import (
	"container/heap"
	"container/ring"
	"fmt"
)

func josephus(n, m int) []int {
	var res []int
	ring := ring.New(n)
	ring.Value = 1
	for i, p := 2, ring.Next(); p != ring; i, p = i+1, p.Next() {
		p.Value = i
	}
	h := ring.Prev()
	for h != h.Next() {
		for i := 1; i < m; i++ {
			h = h.Next()
		}
		res = append(res, h.Unlink(1).Value.(int))
	}
	res = append(res, h.Value.(int))
	return res
}

type intHeap []int

func (h intHeap) Len() int           { return len(h) }
func (h intHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h intHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *intHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}
func (h *intHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func main() {
	fmt.Println(josephus(9, 5))
	h := &intHeap{10, 3, 9, 7, 2, 88, 31, 67}
	heap.Init(h)
	heap.Push(h, 1)
	for h.Len() > 0 {
		fmt.Printf("%d ", heap.Pop(h))
	}
}
时间: 2024-07-31 09:27:06

golang 标准库 container/ring 及 container/heap的相关文章

Golang中使用log(一):Golang 标准库提供的Log

Golang的标准库提供了log的机制,但是该模块的功能较为简单(看似简单,其实他有他的设计思路).不过比手写fmt. Printxxx还是强很多的.至少在输出的位置做了线程安全的保护.其官方手册见Golang log (天朝的墙大家懂的).这里给出一个简单使用的例子: package main import ( "log" ) func main(){ log.Fatal("Come with fatal,exit with 1 \n") } 编译运行后,会看到程

Golang标准库之Buffer

Buffer Go标准库Buffer是一个可变大小的字节缓冲区,可以用Wirte和Read方法操作它,在Go标准库中,定义了如下关于Buffer的数据结构. type Buffer struct { buf []byte // contents are the bytes buf[off : len(buf)] off int // read at &buf[off], write at &buf[len(buf)] runeBytes [utf8.UTFMax]byte // avoid

Golang中使用log(二):Golang 标准库log的实现

前一篇文章我们看到了Golang标准库中log模块的使用,那么它是如何实现的呢?下面我从log.Logger开始逐步分析其实现. 其源码可以参考官方地址 1.Logger结构 首先来看下类型Logger的定义: type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields prefix string // prefix to write at beginning of each

golang标准库文档

Golang标准库文档 https://studygolang.com/pkgdoc go中文官网 https://go-zh.org/doc/ <Go Web 基础>是一套针对 Google 出品的 Go 语言的视频语音教程,主要面向完成 <Go 编程基础>有关 Go Web 开发的学习者. Unknwon/go-web-foundation <Go 编程基础>主要面向新手级别的学习者.Unknwon/go-fundamental-programming <Go

golang标准库 context的使用

本文索引 问题引入 context包简介 示例 问题引入 goroutine为我们提供了轻量级的并发实现,作为golang最大的亮点之一更是备受推崇. goroutine的简单固然有利于我们的开发,但简单总是有代价的,考虑如下例子: func httpDo(req *http.Request, resp *http.Response) { for { select { case <-time.After(5 * time.Second): // 从req读取数据然后发送给resp // 其他的一

golang标准库-strings

字符串处理 字符串在开发中经常用到,包括用户的输入,数据库读取的数据等,我们经常需要对字符串进行分割.连接.转换等操作 字符串操作 下面这些函数来自于strings包,这里介绍一些我平常经常用到的函数,更详细的请参考官方的文档. 1.前缀和后缀 HasPrefix 判断字符串s是否以prefix开头: 函数签名 strings.HasPrefix(s, prefix string) bool HasSuffix 判断字符串 s 是否以 suffix 结尾: 函数签名 strings.HasSuf

golang 标准库io/ioutil,读取文件,生成临时目录/文件

1.读取目录 list, err := ioutil.ReadDir("DIR")//要读取的目录地址DIR,得到列表 if err != nil { fmt.Println("read dir error") return } for _, info := range list { //遍历目录下的内容,获取文件详情,同os.Stat(filename)获取的信息 info.Name()//文件名 info.Mode()//文件权限 info.Size()//文件

golang标准库--io

一.type Reader interface { Read(p []byte)(n int, err error) } Reader是一个包含Read方法的接口 Read方法读取len(p)个字节到p中.它返回读取到的字节数和遇到的错误.即使Read返回n<len(p),在调用过程中也会使用所有p作为暂存空间.如果一些可读取的数据没有len(p),按照惯例Read会返回读取到的数据,而不是等待更多. 当Read成功读取n>0个字节后遇到一个错误或者end-of-file条件,它会返回读取到的

Go标准库

bufio 实现缓冲的I/O bytes 提供了对字节切片操作的函数 crypto 收集了常见的加密常数 errors 实现了操作错误的函数 Expvar 为公共变量提供了一个标准的接口,如服务器中的运算计数器 flag 实现了命令行标记解析 fmt 实现了格式化输入输出 hash 提供了哈希函数接口 html 实现了一个HTML5兼容的分词器和解析器 image 实现了一个基本的二维图像库 io 提供了对I/O原语的基本接口 log 它是一个简单的记录包,提供最基本的日志功能 math 提供了