container
heap
import (
"container/heap"
"fmt"
)
// An IntHeap is a min-heap of ints.
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() {
h := &IntHeap{2, 1, 5}
heap.Init(h)
heap.Push(h, 3)
fmt.Printf("minimum: %d\n", (*h)[0]) // 小根堆
for h.Len() > 0 {
fmt.Printf("%d ", heap.Pop(h))
}
}
list
import (
"container/list"
"fmt"
)
func main() {
// 创建一个新的链表
l := list.New()
e2 := l.PushBack(2)
e5 := l.PushBack(5)
l.InsertBefore(3, e2)
l.InsertAfter(19, e5)
for e := l.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value)
}
}
list 构建 queue/stack
// queue
queue := list.New()
// queue push
queue.pushBack()
// queue pop
front := queue.Front()
queue.Remove(front)
// stack
stack := list.New()
// stack push
stack.pushBack()
// stack pop
back := stack.Back()
stack.Remove(back)
由于 stack 是在一端进行增加删除,所以使用切片来模拟 stack 会更加方便。
// stack
stack := []int{}
// stack push
stack = append(stack, elm)
// stack pop
stack = stack[:len(stack)-1]
LRU
package lru
type LRU struct {
cap int
pos map[int]*Element
root Element // root.next = first, root.pre = last
}
// Element a list element
type Element struct {
Value int
next, pre *Element
}
// New returns an initialized list
func New(cap int) *LRU {
return new(LRU).Init(cap)
}
// Init initializes the lru list
func (lru *LRU) Init(cap int) *LRU {
lru.root.next = &lru.root
lru.root.pre = &lru.root
lru.cap = cap
lru.pos = make(map[int]*Element)
return lru
}
// Query visit a value
func (lru *LRU) Query(v int) {
if lru.pos[v] != nil {
lru.toLast(lru.pos[v])
} else {
if len(lru.pos) == lru.cap {
lru.pop()
}
lru.push(v)
}
}
func (lru *LRU) toLast(elm *Element) {
elmPre, elmNext := elm.pre, elm.next
elmPre.next = elmNext
elmNext.pre = elmPre
curLast := lru.root.pre
curLast.next = elm
elm.pre = curLast
elm.next = &lru.root
lru.root.pre = elm
}
// remove least visit element, which is the head of the list
func (lru *LRU) pop() int {
head := lru.root.next
lru.root.next = head.next
head.next.pre = &lru.root
delete(lru.pos, head.Value)
return head.Value
}
func (lru *LRU) push(v int) {
elm := &Element{
Value: v,
}
curLast := lru.root.pre
curLast.next = elm
lru.root.pre = elm
elm.next = &lru.root
elm.pre = curLast
lru.pos[v] = elm
}