Container
golang实现常用集合
Install / Use
/learn @chentaihan/ContainerREADME
Container
<a href="https://github.com/chentaihan/container/wiki/golang实现常用集合原理介绍">golang实现常用集合原理介绍</a> <a href="https://github.com/chentaihan/container/tree/master/demo">demo</a>
常用集合实现
- <a href="#队列">队列(queue)</a>
- <a href="#队列">优先级队列(priorityQueue)</a>
- <a href="#栈">栈(stack)</a>
- <a href="#排序数组">排序数组(arraySort)</a>
- <a href="#单链表">单链表(singleLinked)</a>
- <a href="https://github.com/chentaihan/container/tree/master/skipLink">跳跃表(skipList)</a>
- <a href="#Map">字典(map)</a>
- <a href="#Set">Set</a>
- <a href="#Set">SetSort</a>
- <a href="#二叉搜索树">二叉搜索树(binaryTree)</a>
- <a href="https://github.com/chentaihan/container/tree/master/trie">前缀树(trie)</a>
- <a href="https://github.com/chentaihan/container/tree/master/btree">B树(btree)</a>
- <a href="#LRU">LRU</a>
- <a href="#LRU">LRU过期时间</a>
- <a href="#堆">堆(heap)</a>
- <a href="https://github.com/chentaihan/container/tree/master/pool">内存池(memoryPool)</a>
- <a href="https://github.com/chentaihan/container/tree/master/common">常用函数</a>
<a id="队列">1:队列</a>
type IQueue interface {
Enqueue(val interface{}) //入队
Dequeue() (interface{}, bool) //出队
Empty() bool //队列是否为空
Len() int //队列长度
Cap() int //队列容量
Peek() (interface{}, bool) //取队首元素
ToList() []interface{} //转换成数组
}
package main
import (
"fmt"
"github.com/chentaihan/container/queue"
)
func main() {
queueTest() //普通队列测试
priorityQueueTest() //优先级队列测试
}
func queueTest() {
size := 2000
var q queue.IQueue = queue.NewQueue(size) //数组实现队列
//var q queue.IQueue = queue.NewQueueLink() //链表实现队列
for i := 0; i < size; i++ {
q.Enqueue(i)
}
if q.Len() != size {
fmt.Println("queue len error")
}
if q.Cap() != size {
fmt.Println("queue cap error,cap=", q.Cap())
}
value, isOK := q.Peek()
if isOK {
if value.(int) != 0 {
fmt.Println("queue peek error")
}
}
for i := 0; i < size; i++ {
q.Enqueue(i)
}
if q.Cap() != size*2 {
fmt.Println("queue cap error,cap=", q.Cap())
}
count := q.Len()
index := 0
for !q.Empty() {
q.Dequeue()
index++
}
if count != index {
fmt.Println(fmt.Sprintf("len = %v != count = %v", index, count))
}
for i := 0; i < size*8; i++ {
q.Enqueue(i)
}
if q.Cap() != size*8 {
fmt.Println(fmt.Sprintf("queue cap error,cap=%v,want cap=%v", q.Cap(), size*8))
}
}
type integer int
func (i integer) GetPriority() int {
return int(i)
}
func (i integer) GetHashCode() int {
return int(i)
}
func priorityQueueTest() {
count := 100
heap := queue.NewPriorityQueue(count)
for i := 0; i < count; i++ {
heap.Push(integer(i))
}
if !heap.Contains(integer(20)) {
fmt.Println("Contain error")
}
if !heap.Remove(integer(20)) {
fmt.Println("remove error")
}
heap.Push(integer(20))
for heap.Len() > 0 {
l := heap.Len()
val := heap.Pop()
if val.GetHashCode() != count-l {
fmt.Println("pop error", val.GetHashCode(), count-l)
}
}
for i := 0; i < count; i++ {
heap.Push(integer(i))
}
list := heap.GetArray()
fmt.Println(list)
heap.Pop()
list = heap.GetArray()
fmt.Println(list)
heap.Push(integer(20))
list = heap.GetArray()
fmt.Println(list)
for heap.Len() > 0 {
heap.Pop()
}
if !heap.Empty() {
fmt.Println("clear error")
}
heap.Clear()
if !heap.Empty() {
fmt.Println("clear error")
}
}
<a id="栈">2:栈</a>
//栈接口
type IStack interface {
Push(x interface{}) //入栈
Pop() (interface{}, bool) //出栈
Top() (interface{}, bool) //栈顶元素
Empty() bool //栈是否为空
Len() int //栈元素个数
Cap() int //栈容量
}
package main
import (
"fmt"
"github.com/chentaihan/container/stack"
)
func main() {
var s stack.IStack = stack.NewStack(100)
//var s stack.IStack = stack.NewStackLink()
size := 10
for i := 0; i < size; i++ {
s.Push(i)
}
if s.Len() != size {
fmt.Println("len error")
}
fmt.Println("cap=", s.Cap())
for !s.Empty() {
if val, exist := s.Top(); exist {
fmt.Println(val)
}
s.Pop()
}
if s.Len() != 0 {
fmt.Println("empty error")
}
}
<a id="排序数组">3:排序数组</a>
//数组接口
type IArray interface {
Add(val IObject) //添加元素
Get(index int) (IObject, bool) //根据下标获取元素
Index(val IObject) int //获取指定值对应的下标,不存在就返回-1
RemoveIndex(index int) (IObject, bool) //删除对应下标的元素
Remove(value IObject) int //删除指定的值
Len() int //元素个数
Clear() //删除所有元素
GetArray() []IObject //返回所有元素(不复制)
Copy() []IObject //复制所有元素
}
type IObject interface {
GetHashCode() int //按照这个函数排序
}
package main
import (
"fmt"
"github.com/chentaihan/container/array"
)
type integer int
func (i integer) GetHashCode() int {
return int(i)
}
func main() {
tests := []struct {
array []integer
result []integer
}{
{
[]integer{1, 3, 2, 4, 6, 5, 9, 8, 7},
[]integer{1, 2, 3, 4, 5, 6, 7, 8, 9},
},
}
for index, test := range tests {
as := array.NewArraySort(0)
for i := 0; i < len(test.array); i++ {
as.Add(test.array[i])
}
var result []array.IObject
for i := 0; i < len(test.result); i++ {
result = append(result, test.result[i])
}
list := as.GetArray()
if !IntEqual(list, result) {
fmt.Println(list, test.result)
fmt.Println("add error ", index)
}
as.Remove(integer(1))
}
}
func IntEqual(nums1, nums2 []array.IObject) bool {
if len(nums1) != len(nums2) {
return false
}
for i := 0; i < len(nums1); i++ {
if nums1[i].GetHashCode() != nums2[i].GetHashCode() {
return false
}
}
return true
}
<a id="单链表">4:单链表</a>
//链表接口
type ILinkList interface {
PushFront(val interface{}) //首部添加元素
PushBack(val interface{}) //尾部添加元素
RemoveFront() (interface{}, bool) //删除首部元素,成功true,失败false
RemoveBack() (interface{}, bool) //删除尾部元素,成功true,失败false
RemoveValue(val interface{}) int ////删除指定值,返回被删除元素数量
Front() (interface{}, bool) //返回首部元素,存在true,不存在false
Back() (interface{}, bool) //返回尾部元素,存在true,不存在false
Len() int //元素个数
Exist(val interface{}) bool //指定元素是否存在
ToList() []interface{} //转换成数组
Clear() //删除所有元素
}
package main
import (
"fmt"
"github.com/chentaihan/container/link"
)
func main() {
list := link.NewLinkedList()
const count = 20
for i := 0; i < count; i++ {
list.PushBack(i)
}
if list.Len() != count {
fmt.Println("len error")
}
first, _ := list.Front()
if first != 0 {
fmt.Println("Front error")
}
last, _ := list.Back()
if last != count-1 {
fmt.Println("Back error")
}
list.RemoveFront()
first, _ = list.Front()
if first != 1 {
fmt.Println("Front error")
}
list.RemoveBack()
last, _ = list.Back()
if last != count-2 {
fmt.Println("Back error ", last)
}
if list.RemoveValue(10) != 1 {
fmt.Println("RemoveValue error")
}
array := list.ToList()
fmt.Println(array)
for i := 0; i < count; i++ {
list.PushBack(10)
}
array = list.ToList()
fmt.Println(array)
if list.RemoveValue(10) != count {
fmt.Println("RemoveValue error")
}
array = list.ToList()
fmt.Println(array)
if list.Exist(10) {
fmt.Println("Exist error")
}
list.PushBack(10)
if !list.Exist(10) {
fmt.Println("Exist error")
}
}
<a id="Map">4:Map</a>
type IMap interface {
Set(key string, value interface{}) //添加元素,已存在就覆盖
Get(key string) (interface{}, bool) //根据key获取元素,bool:true存在,false不存在
Exist(key string) bool //判断key是否存在
Remove(key string) bool //删除指定的key
Len() int //元素个数
Clear() //清除所有元素
Values() []interface{} //获取所有值
Keys() []string //获取所有key
Marshal() ([]byte, error) //序列化
Unmarshal(data []byte) error //反序列化
}
package main
import (
"fmt"
"github.com/chentaihan/container/hashmap"
)
func main() {
tests := []struct {
key string
value string
}{
{
"key1",
"value1",
},
{
"key2",
"value2",
},
{
"key3",
"value3",
},
{
"key4",
"value4",
},
{
"key5",
"value5",
},
}
sm := hashmap.NewMap() //map简单封装
//sm := hashmap.NewMapSync() //同步map
//sm := hashmap.NewTreeMap() //二叉树map
//sm := hashmap.NewLinkMap() //顺序map
for _, test := range tests {
sm.Set(test.key, test.value)
}
for _, test := range tests {
value, _ := sm.Get(test.key)
if value.(string) != test.value {
fmt.Println("equal ", test.key, value.(string), test.value)
}
if !sm.Exist(test.key) {
fmt.Println("exist ", test.key, test.value)
}
}
if sm.Len() != len(tests) {
fmt.Println("len: ", sm.Len(), len(tests))
}
if sm.Exist("asdfghjtre") {
fmt.Println("exist ", "asdfghjtre")
}
data, _ := sm.Marshal()
fmt.Println(string(data))
fmt.Println("success")
dataString := `{"key1":"value1","key2":"value2","key3":"value3","key4":"value4","key5":"value5","key6":"value6"}`
err := sm.Unmarshal([]byte(dataString))
if err != nil {
fmt.Println(err)
}
for _, test := range tests {
if !sm.Exist(test.key) {
fmt.Println("exist ", test.key, test.value)
}
}
if !sm.Exist("key6") {
fmt.Println("key6 not exist ")
}
value6, _ := sm.Get("key6")
if value6 != "value6" {
fmt.Println("key6 value error ", value6)
}
sm.Clear()
if sm.Len() != 0 {
fmt.Println("clear ", sm.Len())
}
}
<a id="Set">5:Set</a>
type ISet interface {
Add(val int) bool //添加元素
Exist(val int) bool //判断是否存在
Remove(val int) bool //删除指定的值
Len() int //元素个数
Clear() //删除所有元素
GetArray() []int //返回所有元素(不复制)
Copy() []int //复制并返回所有元素
}
package main
import (
"fmt"
"github.com/chentaihan/container/common"
"github.com/chentaihan/container/set"
)
func main() {
tests := []struct {
list []int
sortList []int
size int
}{
{
[]int{1, 1, 1, 1, 1, 1, 1},
