From e432cf42e506c0dcd6bc1dd15d6b5facc4f7765e Mon Sep 17 00:00:00 2001 From: hlccd <56643462+hlccd@users.noreply.github.com> Date: Sat, 18 Dec 2021 18:40:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EhashMap=E5=AE=9E=E7=8E=B0,?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B9=8B=E5=89=8D=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=95=B0=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- goSTL/algorithm/hash.go | 99 ++++++ goSTL/data_structure/avlTree/avlTree.go | 46 +-- goSTL/data_structure/avlTree/node.go | 4 +- goSTL/data_structure/hashMap/hashMap.go | 428 ++++++++++++++++++++++++ goSTL/data_structure/list/list.go | 2 +- goSTL/data_structure/vector/vector.go | 54 +-- 6 files changed, 588 insertions(+), 45 deletions(-) create mode 100644 goSTL/algorithm/hash.go create mode 100644 goSTL/data_structure/hashMap/hashMap.go diff --git a/goSTL/algorithm/hash.go b/goSTL/algorithm/hash.go new file mode 100644 index 0000000..793fb46 --- /dev/null +++ b/goSTL/algorithm/hash.go @@ -0,0 +1,99 @@ +package algorithm + +type Hasher func(key interface{}) uint64 + +func GetHash(e interface{}) (hash Hasher) { + if e == nil { + return nil + } + switch e.(type) { + case bool: + return boolHash + case int: + return intHash + case int8: + return int8Hash + case uint8: + return uint8Hash + case int16: + return int16Hash + case uint16: + return uint16Hash + case int32: + return int32Hash + case uint32: + return uint32Hash + case int64: + return int64Hash + case uint64: + return uint64Hash + case float32: + return float32Hash + case float64: + return float64Hash + case complex64: + return complex64Hash + case complex128: + return complex128Hash + case string: + return stringHash + } + return nil +} +func boolHash(key interface{}) uint64 { + if key.(bool) { + return 1 + } + return 0 +} +func intHash(key interface{}) uint64 { + return uint64(key.(int) * key.(int)/2) +} +func int8Hash(key interface{}) uint64 { + return uint64(key.(int8) * key.(int8)/2) +} +func uint8Hash(key interface{}) uint64 { + return uint64(key.(uint8) * key.(uint8)/2) +} +func int16Hash(key interface{}) uint64 { + return uint64(key.(int16) * key.(int16)/2) +} +func uint16Hash(key interface{}) uint64 { + return uint64(key.(uint16) * key.(uint16)/2) +} +func int32Hash(key interface{}) uint64 { + return uint64(key.(int32) * key.(int32)/2) +} +func uint32Hash(key interface{}) uint64 { + return uint64(key.(uint32) * key.(uint32)/2) +} +func int64Hash(key interface{}) uint64 { + return uint64(key.(int64) * key.(int64)/2) +} +func uint64Hash(key interface{}) uint64 { + return uint64(key.(uint64) * key.(uint64)/2) +} +func float32Hash(key interface{}) uint64 { + return uint64(key.(float32) * key.(float32)/2) +} +func float64Hash(key interface{}) uint64 { + return uint64(key.(float64) * key.(float64)/2) +} +func complex64Hash(key interface{}) uint64 { + r := uint64(real(key.(complex64))) + i := uint64(imag(key.(complex64))) + return uint64Hash(r) + uint64Hash(i) +} +func complex128Hash(key interface{}) uint64 { + r := uint64(real(key.(complex64))) + i := uint64(imag(key.(complex64))) + return uint64Hash(r) + uint64Hash(i) +} +func stringHash(key interface{}) uint64 { + bs := []byte(key.(string)) + ans := uint64(0) + for i := range bs { + ans += uint64(bs[i] * 251) + } + return ans +} diff --git a/goSTL/data_structure/avlTree/avlTree.go b/goSTL/data_structure/avlTree/avlTree.go index 51d476f..dbbb37b 100644 --- a/goSTL/data_structure/avlTree/avlTree.go +++ b/goSTL/data_structure/avlTree/avlTree.go @@ -21,7 +21,7 @@ import ( //同时保存该二叉树已经存储了多少个元素 //二叉树中排序使用的比较器在创建时传入,若不传入则在插入首个节点时从默认比较器中寻找 //创建时传入是否允许该二叉树出现重复值,如果不允许则进行覆盖,允许则对节点数目增加即可 -type avlTree struct { +type AvlTree struct { root *node //根节点指针 size int //存储元素数量 cmp comparator.Comparator //比较器 @@ -37,8 +37,8 @@ type avlTreer interface { Size() (num int) //返回该二叉树中保存的元素个数 Clear() //清空该二叉树 Empty() (b bool) //判断该二叉树是否为空 - Insert(e interface{}) //向二叉树中插入元素e - Erase(e interface{}) //从二叉树中删除元素e + Insert(e interface{}) (b bool) //向二叉树中插入元素e + Erase(e interface{}) (b bool) //从二叉树中删除元素e Count(e interface{}) (num int) //从二叉树中寻找元素e并返回其个数 } @@ -52,7 +52,7 @@ type avlTreer interface { //@param isMulti bool 该二叉树是否保存重复值? //@param Cmp ...comparator.Comparator avlTree比较器集 //@return avl *avlTree 新建的avlTree指针 -func New(isMulti bool, cmps ...comparator.Comparator) (avl *avlTree) { +func New(isMulti bool, cmps ...comparator.Comparator) (avl *AvlTree) { //判断是否有传入比较器,若有则设为该二叉树默认比较器 var cmp comparator.Comparator if len(cmps) == 0 { @@ -60,7 +60,7 @@ func New(isMulti bool, cmps ...comparator.Comparator) (avl *avlTree) { } else { cmp = cmps[0] } - return &avlTree{ + return &AvlTree{ root: nil, size: 0, cmp: cmp, @@ -76,12 +76,12 @@ func New(isMulti bool, cmps ...comparator.Comparator) (avl *avlTree) { //@receiver avl *avlTree 接受者avlTree的指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (avl *avlTree) Iterator() (i *Iterator.Iterator) { +func (avl *AvlTree) Iterator() (i *Iterator.Iterator) { if avl == nil { return nil } avl.mutex.Lock() - es:=avl.root.inOrder() + es := avl.root.inOrder() i = Iterator.New(&es) avl.mutex.Unlock() return i @@ -95,7 +95,7 @@ func (avl *avlTree) Iterator() (i *Iterator.Iterator) { //@receiver avl *avlTree 接受者avlTree的指针 //@param nil //@return num int 容器中实际使用元素所占空间大小 -func (avl *avlTree) Size() (num int) { +func (avl *AvlTree) Size() (num int) { if avl == nil { return 0 } @@ -110,7 +110,7 @@ func (avl *avlTree) Size() (num int) { //@receiver avl *avlTree 接受者avlTree的指针 //@param nil //@return nil -func (avl *avlTree) Clear() { +func (avl *AvlTree) Clear() { if avl == nil { return } @@ -130,7 +130,7 @@ func (avl *avlTree) Clear() { //@receiver avl *avlTree 接受者avlTree的指针 //@param nil //@return b bool 该容器是空的吗? -func (avl *avlTree) Empty() (b bool) { +func (avl *AvlTree) Empty() (b bool) { if avl == nil { return true } @@ -148,10 +148,10 @@ func (avl *avlTree) Empty() (b bool) { // 当节点左右子树高度差超过1时将进行旋转以保持平衡 //@receiver avl *avlTree 接受者avlTree的指针 //@param e interface{} 待插入元素 -//@return nil -func (avl *avlTree) Insert(e interface{}) { +//@return b bool 添加成功? +func (avl *AvlTree) Insert(e interface{}) (b bool){ if avl == nil { - return + return false } avl.mutex.Lock() if avl.Empty() { @@ -165,16 +165,16 @@ func (avl *avlTree) Insert(e interface{}) { avl.root = newNode(e) avl.size = 1 avl.mutex.Unlock() - return + return true } //从根节点进行插入,并返回节点,同时返回是否插入成功 - var b bool avl.root, b = avl.root.insert(e, avl.isMulti, avl.cmp) if b { //插入成功,数量+1 avl.size++ } avl.mutex.Unlock() + return b } //@title Erase @@ -186,13 +186,13 @@ func (avl *avlTree) Insert(e interface{}) { // 如果该二叉树仅持有一个元素且根节点等价于待删除元素,则将二叉树根节点置为nil //@receiver avl *avlTree 接受者avlTree的指针 //@param e interface{} 待删除元素 -//@return nil -func (avl *avlTree) Erase(e interface{}) { +//@return b bool 删除成功 +func (avl *AvlTree) Erase(e interface{}) (b bool) { if avl == nil { - return + return false } if avl.Empty() { - return + return false } avl.mutex.Lock() if avl.size == 1 && avl.cmp(avl.root.value, e) == 0 { @@ -200,15 +200,15 @@ func (avl *avlTree) Erase(e interface{}) { avl.root = nil avl.size = 0 avl.mutex.Unlock() - return + return true } //从根节点进行插入,并返回节点,同时返回是否删除成功 - var b bool avl.root, b = avl.root.erase(e, avl.cmp) if b { avl.size-- } avl.mutex.Unlock() + return b } //@title Count @@ -221,7 +221,7 @@ func (avl *avlTree) Erase(e interface{}) { //@receiver avl *avlTree 接受者avlTree的指针 //@param e interface{} 待查找元素 //@return num int 待查找元素在二叉树中存储的个数 -func (avl *avlTree) Count(e interface{}) (num int) { +func (avl *AvlTree) Count(e interface{}) (num int) { if avl == nil { //二叉树为空,返回0 return 0 @@ -244,7 +244,7 @@ func (avl *avlTree) Count(e interface{}) (num int) { //@receiver avl *avlTree 接受者avlTree的指针 //@param e interface{} 待查找索引元素 //@return ans interface{} 待查找索引元素所指向的元素 -func (avl *avlTree) Find(e interface{}) (ans interface{}) { +func (avl *AvlTree) Find(e interface{}) (ans interface{}) { if avl == nil { //二叉树为空,返回0 return 0 diff --git a/goSTL/data_structure/avlTree/node.go b/goSTL/data_structure/avlTree/node.go index 6ee759a..663dd89 100644 --- a/goSTL/data_structure/avlTree/node.go +++ b/goSTL/data_structure/avlTree/node.go @@ -361,11 +361,11 @@ func (n *node) find(e interface{}, isMulti bool, cmp comparator.Comparator) (ans } //n中承载元素小于e,从右子树继续查找并返回结果 if cmp(n.value, e) < 0 { - return n.right.count(e, isMulti, cmp) + return n.right.find(e, isMulti, cmp) } //n中承载元素大于e,从左子树继续查找并返回结果 if cmp(n.value, e) > 0 { - return n.left.count(e, isMulti, cmp) + return n.left.find(e, isMulti, cmp) } //n中承载元素等于e,直接返回结果 return n.value diff --git a/goSTL/data_structure/hashMap/hashMap.go b/goSTL/data_structure/hashMap/hashMap.go new file mode 100644 index 0000000..b0347a8 --- /dev/null +++ b/goSTL/data_structure/hashMap/hashMap.go @@ -0,0 +1,428 @@ +package hashMap + +//@Title hashMap +//@Description +// 哈希映射-hash map +// 分为两层,第一层以vector实现,当出现hash冲突时以avl树存储即第二层 +// 若为基本数据类型可不用传入hash函数,否则需要传入自定义hash函数 +// 所有key不可重复,但value可重复,key不应为nil +// 扩容因子为0.75,当存储数超过0.75倍总容量时应当扩容 +// 使用互斥锁实现并发控制 +import ( + "github.com/hlccd/goSTL/algorithm" + "github.com/hlccd/goSTL/data_structure/avlTree" + "github.com/hlccd/goSTL/data_structure/vector" + "github.com/hlccd/goSTL/utils/comparator" + "github.com/hlccd/goSTL/utils/iterator" + "sync" +) + +//hashMap哈希映射结构体 +//该实例存储第一层vector的指针 +//同时保存hash函数 +//哈希映射中的hash函数在创建时传入,若不传入则在插入首个key-value时从默认hash函数中寻找 +type hashMap struct { + arr *vector.Vector //第一层的vector + hash algorithm.Hasher //hash函数 + size uint64 //当前存储数量 + cap uint64 //vector的容量 + mutex sync.Mutex //并发控制锁 +} + +//索引结构体 +//存储key-value结构 +type indexes struct { + key interface{} + value interface{} +} + +//hashMap哈希映射容器接口 +//存放了hashMap哈希映射可使用的函数 +//对应函数介绍见下方 +type hashMaper interface { + Iterator() (i *Iterator.Iterator) //返回一个包含hashMap容器中所有value的迭代器 + Size() (num uint64) //返回hashMap已存储的元素数量 + Cap() (num uint64) //返回hashMap中的存放空间的容量 + Clear() //清空hashMap + Empty() (b bool) //返回hashMap是否为空 + Insert(key, value interface{}) (b bool) //向hashMap插入以key为索引的value,若存在会覆盖 + Erase(key interface{}) (b bool) //删除hashMap中以key为索引的value + GetKeys() (keys []interface{}) //返回hashMap中所有的keys + Get(key interface{}) (value interface{}) //以key为索引寻找vlue +} + +//@title New +//@description +// 新建一个hashMap哈希映射容器并返回 +// 初始vector长度为16 +// 若有传入的hash函数,则将传入的第一个hash函数设为该hash映射的hash函数 +//@receiver nil +//@param Cmp ...algorithm.Hasher hashMap的hash函数集 +//@return hm *hashMap 新建的hashMap指针 +func New(hash ...algorithm.Hasher) (hm *hashMap) { + var h algorithm.Hasher + if len(hash) == 0 { + h = nil + } else { + h = hash[0] + } + cmp := func(a, b interface{}) int { + ka, kb := a.(*indexes), b.(*indexes) + return comparator.GetCmp(ka.key)(ka.key, kb.key) + } + //新建vector并将其扩容到16 + v := vector.New() + for i := 0; i < 16; i++ { + //vector中嵌套avl树 + v.PushBack(avlTree.New(false, cmp)) + } + return &hashMap{ + arr: v, + hash: h, + size: 0, + cap: 16, + mutex: sync.Mutex{}, + } +} + +//@title Iterator +//@description +// 以hashMap哈希映射做接收者 +// 将该hashMap中所有保存的索引指针的value放入迭代器中 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return i *iterator.Iterator 新建的Iterator迭代器指针 +func (hm *hashMap) Iterator() (i *Iterator.Iterator) { + if hm == nil { + return nil + } + if hm.arr == nil { + return nil + } + hm.mutex.Lock() + //取出hashMap中存放的所有value + values := make([]interface{}, 0, 1) + for i := uint64(0); i < hm.arr.Size(); i++ { + avl := hm.arr.At(i).(*avlTree.AvlTree) + ite := avl.Iterator() + es := make([]interface{}, 0, 1) + for j := ite.Begin(); j.HasNext(); j.Next() { + idx := j.Value().(*indexes) + es = append(es, idx.value) + } + values = append(values, es...) + } + //将所有value放入迭代器中 + i = Iterator.New(&values) + hm.mutex.Unlock() + return i +} + +//@title Size +//@description +// 以hashMap哈希映射做接收者 +// 返回该容器当前含有元素的数量 +// 如果容器为nil返回0 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return num int 容器中实际使用元素所占空间大小 +func (hm *hashMap) Size() (num uint64) { + if hm == nil { + return 0 + } + return hm.size +} + +//@title Cap +//@description +// 以hashMap哈希映射做接收者 +// 返回该容器当前容量 +// 如果容器为nil返回0 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return num int 容器中实际占用的容量大小 +func (hm *hashMap) Cap() (num uint64) { + if hm == nil { + return 0 + } + return hm.cap +} + +//@title Clear +//@description +// 以hashMap哈希映射做接收者 +// 将该容器中所承载的元素清空 +// 将该容器的size置0,容量置为16,vector重建并扩容到16 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return nil +func (hm *hashMap) Clear() { + if hm == nil { + return + } + hm.mutex.Lock() + //重建vector并扩容到16 + v := vector.New() + cmp := func(a, b interface{}) int { + ka, kb := a.(*indexes), b.(*indexes) + return comparator.GetCmp(ka.key)(ka.key, kb.key) + } + for i := 0; i < 16; i++ { + v.PushBack(avlTree.New(false, cmp)) + } + hm.arr = v + hm.size = 0 + hm.cap = 16 + hm.mutex.Unlock() +} + +//@title Empty +//@description +// 以hashMap哈希映射做接收者 +// 判断该哈希映射中是否含有元素 +// 如果含有元素则不为空,返回false +// 如果不含有元素则说明为空,返回true +// 如果容器不存在,返回true +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return b bool 该容器是空的吗? +func (hm *hashMap) Empty() (b bool) { + if hm == nil { + return false + } + return hm.size > 0 +} + +//@title Insert +//@description +// 以hashMap哈希映射做接收者 +// 向哈希映射入元素e,若已存在相同key则进行覆盖,覆盖仍然视为插入成功 +// 若不存在相同key则直接插入即可 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param key interface{} 待插入元素的key +//@param value interface{} 待插入元素的value +//@return b bool 添加成功? +func (hm *hashMap) Insert(key, value interface{}) (b bool) { + if hm == nil { + return false + } + if hm.arr == nil { + return false + } + if hm.hash == nil { + hm.hash = algorithm.GetHash(key) + } + if hm.hash == nil { + return false + } + hm.mutex.Lock() + //计算hash值并找到对应的avl树 + hash := hm.hash(key) % hm.cap + avl := hm.arr.At(hash).(*avlTree.AvlTree) + idx := &indexes{ + key: key, + value: value, + } + //判断是否存在该avl树中 + if avl.Count(idx) == 0 { + //avl树中不存在相同key,插入即可 + avl.Insert(idx) + hm.size++ + if hm.size >= hm.cap/4*3 { + //当达到扩容条件时候进行扩容 + hm.expend() + } + } else { + //覆盖 + avl.Insert(idx) + } + hm.mutex.Unlock() + return true +} + +//@title expend +//@description +// 以hashMap哈希映射做接收者 +// 对原vector进行扩容 +// 将所有的key-value取出,让vector自行扩容并清空原有结点 +// 扩容后将所有的key-value重新插入vector中 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return nil +func (hm *hashMap) expend() { + //取出所有的key-value + idxs := make([]*indexes, 0, hm.size) + for i := uint64(0); i < hm.arr.Size(); i++ { + avl := hm.arr.At(i).(*avlTree.AvlTree) + ite := avl.Iterator() + for j := ite.Begin(); j.HasNext(); j.Next() { + idxs = append(idxs, j.Value().(*indexes)) + } + } + cmp := func(a, b interface{}) int { + ka, kb := a.(*indexes), b.(*indexes) + return comparator.GetCmp(ka.key)(ka.key, kb.key) + } + //对vector进行扩容,扩容到其容量上限即可 + hm.arr.PushBack(avlTree.New(false, cmp)) + for i := uint64(0); i < hm.arr.Size()-1; i++ { + hm.arr.At(i).(*avlTree.AvlTree).Clear() + } + for i := hm.arr.Size(); i < hm.arr.Cap(); i++ { + hm.arr.PushBack(avlTree.New(false, cmp)) + } + //将vector容量设为hashMap容量 + hm.cap = hm.arr.Cap() + //重新将所有的key-value插入到hashMap中去 + for i := 0; i < len(idxs); i++ { + key, value := idxs[i].key, idxs[i].value + hash := hm.hash(key) % hm.cap + avl := hm.arr.At(hash).(*avlTree.AvlTree) + idx := &indexes{ + key: key, + value: value, + } + avl.Insert(idx) + } +} + +//@title Erase +//@description +// 以hashMap哈希映射做接收者 +// 从hashMap中删除以key为索引的value +// 若存在则删除,否则直接结束,删除成功后size-1 +// 删除后可能出现size<0.75/2*cap且大于16,此时要缩容 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param key interface{} 待删除元素的key +//@return b bool 删除成功? +func (hm *hashMap) Erase(key interface{}) (b bool) { + if hm == nil { + return false + } + if hm.arr == nil { + return false + } + if hm.hash == nil { + return false + } + hm.mutex.Lock() + //计算该key的hash值 + hash := hm.hash(key) % hm.cap + avl := hm.arr.At(hash).(*avlTree.AvlTree) + idx := &indexes{ + key: key, + value: nil, + } + //从对应的avl树中删除该key-value + b = avl.Erase(idx) + if b { + //删除成功,此时size-1,同时进行缩容判断 + hm.size-- + if hm.size < hm.cap/8*3 && hm.cap > 16 { + hm.shrink() + } + } + hm.mutex.Unlock() + return b +} + +//@title shrink +//@description +// 以hashMap哈希映射做接收者 +// 对原vector进行缩容 +// 将所有的key-value取出,让vector自行缩容并清空所有结点 +// 当vector容量与缩容开始时不同时则视为缩容结束 +// 随容后将所有的key-value重新插入vector中 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return nil +func (hm *hashMap) shrink() { + //取出所有key-value + idxs := make([]*indexes, 0, hm.size) + for i := uint64(0); i < hm.arr.Size(); i++ { + avl := hm.arr.At(i).(*avlTree.AvlTree) + ite := avl.Iterator() + for j := ite.Begin(); j.HasNext(); j.Next() { + idxs = append(idxs, j.Value().(*indexes)) + } + } + //进行缩容,当vector的cap与初始不同时,说明缩容结束 + cap := hm.arr.Cap() + for ; cap == hm.arr.Cap(); { + hm.arr.PopBack() + } + hm.cap = hm.arr.Cap() + //将所有的key-value重新放入hashMap中 + for i := 0; i < len(idxs); i++ { + key, value := idxs[i].key, idxs[i].value + hash := hm.hash(key) % hm.cap + avl := hm.arr.At(hash).(*avlTree.AvlTree) + idx := &indexes{ + key: key, + value: value, + } + avl.Insert(idx) + } +} + +//@title GetKeys +//@description +// 以hashMap哈希映射做接收者 +// 返回该hashMap中所有的key +//@receiver hm *hashMap 接受者hashMap的指针 +//@param nil +//@return keys []interface{} hashMap中的所有key +func (hm *hashMap) GetKeys() (keys []interface{}) { + if hm == nil { + return nil + } + if hm.arr == nil { + return nil + } + hm.mutex.Lock() + keys = make([]interface{}, 0, 1) + for i := uint64(0); i < hm.arr.Size(); i++ { + avl := hm.arr.At(i).(*avlTree.AvlTree) + ite := avl.Iterator() + es := make([]interface{}, 0, 1) + for j := ite.Begin(); j.HasNext(); j.Next() { + idx := j.Value().(*indexes) + es = append(es, idx.key) + } + keys = append(keys, es...) + } + hm.mutex.Unlock() + return keys +} + +//@title Get +//@description +// 以hashMap哈希映射做接收者 +// 以key寻找到对应的value并返回 +//@receiver hm *hashMap 接受者hashMap的指针 +//@param keys interface{} 待查找元素的key +//@return keys interface{} 待查找元素的value +func (hm *hashMap) Get(key interface{}) (value interface{}) { + if hm == nil { + return + } + if hm.arr == nil { + return + } + if hm.hash == nil { + hm.hash = algorithm.GetHash(key) + } + if hm.hash == nil { + return + } + hm.mutex.Lock() + //计算hash值 + hash := hm.hash(key) % hm.cap + //从avl树中找到对应该hash值的key-value + info := hm.arr.At(hash).(*avlTree.AvlTree).Find(&indexes{key: key, value: nil}) + hm.mutex.Unlock() + if info == nil { + return nil + } + return info.(*indexes).value +} diff --git a/goSTL/data_structure/list/list.go b/goSTL/data_structure/list/list.go index b83c2cd..c302a16 100644 --- a/goSTL/data_structure/list/list.go +++ b/goSTL/data_structure/list/list.go @@ -43,7 +43,7 @@ type lister interface { Get(idx uint64) (e interface{}) //获得下标为idx的元素 Set(idx uint64, e interface{}) //在下标为idx的位置上放置元素e IndexOf(e interface{}, Equ ...comparator.Equaler) (idx uint64) //返回和元素e相同的第一个下标 - SubList(begin, num uint64) (newList *list) //从begin开始复制最多num个元素以形成新的链表 + SubList(begin, num uint64) (newList *List) //从begin开始复制最多num个元素以形成新的链表 } //@title New diff --git a/goSTL/data_structure/vector/vector.go b/goSTL/data_structure/vector/vector.go index 8abb29d..6eb16a4 100644 --- a/goSTL/data_structure/vector/vector.go +++ b/goSTL/data_structure/vector/vector.go @@ -32,6 +32,7 @@ type Vector struct { mutex sync.Mutex //并发控制锁 } +const bound = 4294967296 //vector向量容器接口 //存放了vector容器可使用的函数 //对应函数介绍见下方 @@ -40,6 +41,7 @@ type vectorer interface { Iterator() (i *Iterator.Iterator) //返回一个包含vector所有元素的迭代器 Sort(Cmp ...comparator.Comparator) //利用比较器对其进行排序 Size() (num uint64) //返回vector的长度 + Cap() (num uint64) //返回vector的容量 Clear() //清空vector Empty() (b bool) //返回vector是否为空,为空则返回true反之返回false PushBack(e interface{}) //向vector末尾插入一个元素 @@ -148,6 +150,20 @@ func (v *Vector) Size() (num uint64) { return v.len } +//@title Cap +//@description +// 以vector向量容器做接收者 +// 返回该容器当前容量 +//@receiver v *Vector 接受者vector的指针 +//@param nil +//@return num int 容器中实际使用元素所占空间大小 +func (v *Vector) Cap() (num uint64) { + if v == nil { + v = New() + } + return v.cap +} + //@title Clear //@description // 以vector向量容器做接收者 @@ -192,7 +208,7 @@ func (v *Vector) Empty() (b bool) { // 在容器尾部插入元素 // 若长度小于容量时,则对以长度为下标的位置进行覆盖,同时len++ // 若长度等于容量时,需要进行扩容 -// 对于扩容而言,当容量小于2^16时,直接将容量翻倍,否则将容量增加2^16 +// 对于扩容而言,当容量小于bound时,直接将容量翻倍,否则将容量增加bound //@receiver v *Vector 接受者vector的指针 //@param e interface{} 待插入元素 //@return nil @@ -206,15 +222,15 @@ func (v *Vector) PushBack(e interface{}) { v.data[v.len] = e } else { //冗余不足,需要扩容 - if v.cap <= 65536 { + if v.cap <= bound { //容量翻倍 if v.cap == 0 { v.cap = 1 } v.cap *= 2 } else { - //容量增加2^16 - v.cap += 65536 + //容量增加bound + v.cap += bound } //复制扩容前的元素 tmp := make([]interface{}, v.cap, v.cap) @@ -232,7 +248,7 @@ func (v *Vector) PushBack(e interface{}) { // 弹出容器最后一个元素,同时长度--即可 // 若容器为空,则不进行弹出 // 当弹出元素后,可能进行缩容 -// 当容量和实际使用差值超过2^16时,容量直接减去2^16 +// 当容量和实际使用差值超过bound时,容量直接减去bound // 否则,当实际使用长度是容量的一半时,进行折半缩容 //@receiver v *Vector 接受者vector的指针 //@param nil @@ -246,9 +262,9 @@ func (v *Vector) PopBack() { } v.mutex.Lock() v.len-- - if v.cap-v.len >= 65536 { - //容量和实际使用差值超过2^16时,容量直接减去2^16 - v.cap -= 65536 + if v.cap-v.len >= bound { + //容量和实际使用差值超过bound时,容量直接减去bound + v.cap -= bound tmp := make([]interface{}, v.cap, v.cap) copy(tmp, v.data) v.data = tmp @@ -283,15 +299,15 @@ func (v *Vector) Insert(idx uint64, e interface{}) { var tmp []interface{} if v.len >= v.cap { //冗余不足,进行扩容 - if v.cap <= 65536 { + if v.cap <= bound { //容量翻倍 if v.cap == 0 { v.cap = 1 } v.cap *= 2 } else { - //容量增加2^16 - v.cap += 65536 + //容量增加bound + v.cap += bound } //复制扩容前的元素 tmp = make([]interface{}, v.cap, v.cap) @@ -332,9 +348,9 @@ func (v *Vector) Erase(idx uint64) { v.data[p] = v.data[p+1] } v.len-- - if v.cap-v.len >= 65536 { - //容量和实际使用差值超过2^16时,容量直接减去2^16 - v.cap -= 65536 + if v.cap-v.len >= bound { + //容量和实际使用差值超过bound时,容量直接减去bound + v.cap -= bound tmp := make([]interface{}, v.cap, v.cap) copy(tmp, v.data) v.data = tmp @@ -371,7 +387,7 @@ func (v *Vector) Reverse() { tmp := make([]interface{}, v.len, v.len) copy(tmp, v.data) v.data = tmp - v.cap=v.len + v.cap = v.len } for i := uint64(0); i < v.len/2; i++ { v.data[i], v.data[v.len-i-1] = v.data[v.len-i-1], v.data[i] @@ -391,7 +407,7 @@ func (v *Vector) Reverse() { //@return e interface{} 从容器中查找的第idx位元素 func (v *Vector) At(idx uint64) (e interface{}) { if v == nil { - v=New() + v = New() return nil } v.mutex.Lock() @@ -418,7 +434,7 @@ func (v *Vector) At(idx uint64) (e interface{}) { //@return e interface{} 容器的第一个元素 func (v *Vector) Front() (e interface{}) { if v == nil { - v=New() + v = New() return nil } v.mutex.Lock() @@ -441,7 +457,7 @@ func (v *Vector) Front() (e interface{}) { //@return e interface{} 容器的最后一个元素 func (v *Vector) Back() (e interface{}) { if v == nil { - v=New() + v = New() return nil } v.mutex.Lock() @@ -452,4 +468,4 @@ func (v *Vector) Back() (e interface{}) { } v.mutex.Unlock() return nil -} \ No newline at end of file +}