From 86d66abc0f5f54c71a4806718904b2778dbf9415 Mon Sep 17 00:00:00 2001 From: hlccd <56643462+hlccd@users.noreply.github.com> Date: Sun, 12 Dec 2021 20:33:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86=E6=A0=91=E5=A0=86?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E7=8E=B0,=E7=BA=BF=E7=A8=8B=E5=AE=89?= =?UTF-8?q?=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- goSTL/data_structure/bitmap/bitmap.go | 28 +- goSTL/data_structure/bsTree/bsTree.go | 36 +-- goSTL/data_structure/deque/deque.go | 64 ++-- goSTL/data_structure/deque/deque_test.go | 36 +++ goSTL/data_structure/list/list.go | 54 ++-- .../priority_queue/priority_queue.go | 40 +-- goSTL/data_structure/queue/queue.go | 42 +-- goSTL/data_structure/ring/ring.go | 48 +-- goSTL/data_structure/stack/stack.go | 36 +-- goSTL/data_structure/treap/node.go | 304 ++++++++++++++++++ goSTL/data_structure/treap/treap.go | 242 ++++++++++++++ goSTL/data_structure/vector/vector.go | 61 ++-- 12 files changed, 788 insertions(+), 203 deletions(-) create mode 100644 goSTL/data_structure/deque/deque_test.go create mode 100644 goSTL/data_structure/treap/node.go create mode 100644 goSTL/data_structure/treap/treap.go diff --git a/goSTL/data_structure/bitmap/bitmap.go b/goSTL/data_structure/bitmap/bitmap.go index 60ed4c6..2e54b40 100644 --- a/goSTL/data_structure/bitmap/bitmap.go +++ b/goSTL/data_structure/bitmap/bitmap.go @@ -12,7 +12,7 @@ package bitmap //包含其用于存储的uint64元素切片 //选用uint64是为了更多的利用bit位 -type bitmap struct { +type Bitmap struct { bits []uint64 } @@ -34,9 +34,9 @@ type bitmaper interface { // 初始bitmap的切片数组为空 //@receiver nil //@param nil -//@return bm *bitmap 新建的bitmap指针 -func New() (bm *bitmap) { - return &bitmap{ +//@return bm *Bitmap 新建的bitmap指针 +func New() (bm *Bitmap) { + return &Bitmap{ bits: make([]uint64, 0, 0), } } @@ -48,10 +48,10 @@ func New() (bm *bitmap) { // 当num大于当前所能存储的位范围时,需要进行扩增 // 若要插入的位比冗余的多不足2^16即1024*64时,则新增1024个uint64 // 否则则直接增加到可以容纳第num位的位置,以此可以提高冗余量,避免多次增加 -//@receiver bm *bitmap 接受者bitmap的指针 +//@receiver bm *Bitmap 接受者bitmap的指针 //@param num int 待插入的位的下标 //@return nil -func (bm *bitmap) Insert(num uint) { +func (bm *Bitmap) Insert(num uint) { //bm不存在时直接结束 if bm == nil { return @@ -86,10 +86,10 @@ func (bm *bitmap) Insert(num uint) { // 对于缩容而言,从后往前遍历判断最后有多少个连续的0,即可以删除的多少组 // 若可删除的组大于总组数的一半则进行删除,否则则当作冗余量即可 // 若可删除的组数超过1024个时,则先删除1024个 -//@receiver bm *bitmap 接受者bitmap的指针 +//@receiver bm *Bitmap 接受者bitmap的指针 //@param num int 待删除的位的下标 //@return nil -func (bm *bitmap) Delete(num uint) { +func (bm *Bitmap) Delete(num uint) { //bm不存在时直接结束 if bm == nil { return @@ -127,10 +127,10 @@ func (bm *bitmap) Delete(num uint) { // 检验第num位在位图中是否存在 // 当num大于当前所能存储的位范围时,直接返回false // 否则判断第num为是否为1,为1返回true,否则返回false -//@receiver bm *bitmap 接受者bitmap的指针 +//@receiver bm *Bitmap 接受者bitmap的指针 //@param num int 待检测位的下标 //@return b bool 第num位存在于位图中 -func (bm *bitmap) Check(num uint) (b bool) { +func (bm *Bitmap) Check(num uint) (b bool) { //bm不存在时直接返回false并结束 if bm == nil { return false @@ -151,10 +151,10 @@ func (bm *bitmap) Check(num uint) (b bool) { // 以bitmap位图容器做接收者 // 返回所有在位图中存在的元素的下标 // 返回的下标是单调递增序列 -//@receiver bm *bitmap 接受者bitmap的指针 +//@receiver bm *Bitmap 接受者bitmap的指针 //@param nil //@return nums []uint 所有在位图中存在的元素的下标集合 -func (bm *bitmap) All() (nums []uint) { +func (bm *Bitmap) All() (nums []uint) { //对要返回的集合进行初始化,以避免返回nil nums=make([]uint,0,0) //bm不存在时直接返回并结束 @@ -177,10 +177,10 @@ func (bm *bitmap) All() (nums []uint) { //@description // 以bitmap位图容器做接收者 // 清空位图 -//@receiver bm *bitmap 接受者bitmap的指针 +//@receiver bm *Bitmap 接受者bitmap的指针 //@param nil //@return nums []uint 所有在位图中存在的元素的下标集合 -func (bm *bitmap) Clear() { +func (bm *Bitmap) Clear() { if bm == nil { return } diff --git a/goSTL/data_structure/bsTree/bsTree.go b/goSTL/data_structure/bsTree/bsTree.go index cdf14fb..605a14b 100644 --- a/goSTL/data_structure/bsTree/bsTree.go +++ b/goSTL/data_structure/bsTree/bsTree.go @@ -21,7 +21,7 @@ import ( //同时保存该二叉树已经存储了多少个元素 //二叉树中排序使用的比较器在创建时传入,若不传入则在插入首个节点时从默认比较器中寻找 //创建时传入是否允许该二叉树出现重复值,如果不允许则进行覆盖,允许则对节点数目增加即可 -type bsTree struct { +type BsTree struct { root *node //根节点指针 size uint64 //存储元素数量 cmp comparator.Comparator //比较器 @@ -51,8 +51,8 @@ type bsTreeer interface { //@receiver nil //@param isMulti bool 该二叉树是否保存重复值? //@param Cmp ...comparator.Comparator bsTree比较器集 -//@return bs *bsTree 新建的bsTree指针 -func New(isMulti bool, Cmp ...comparator.Comparator) (bs *bsTree) { +//@return bs *BsTree 新建的bsTree指针 +func New(isMulti bool, Cmp ...comparator.Comparator) (bs *BsTree) { //判断是否有传入比较器,若有则设为该二叉树默认比较器 var cmp comparator.Comparator if len(Cmp) == 0 { @@ -60,7 +60,7 @@ func New(isMulti bool, Cmp ...comparator.Comparator) (bs *bsTree) { } else { cmp = Cmp[0] } - return &bsTree{ + return &BsTree{ root: nil, size: 0, cmp: cmp, @@ -74,10 +74,10 @@ func New(isMulti bool, Cmp ...comparator.Comparator) (bs *bsTree) { // 以bsTree二叉搜索树做接收者 // 将该二叉树中所有保存的元素将从根节点开始以中缀序列的形式放入迭代器中 // 若允许重复存储则对于重复元素进行多次放入 -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (bs *bsTree) Iterator() (i *Iterator.Iterator) { +func (bs *BsTree) Iterator() (i *Iterator.Iterator) { if bs == nil { //创建一个允许插入重复值的二叉搜 bs = New(true) @@ -94,10 +94,10 @@ func (bs *bsTree) Iterator() (i *Iterator.Iterator) { // 以bsTree二叉搜索树做接收者 // 返回该容器当前含有元素的数量 // 如果容器为nil则创建一个并返回其承载的元素个数 -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param nil //@return num uint64 容器中实际使用元素所占空间大小 -func (bs *bsTree) Size() (num uint64) { +func (bs *BsTree) Size() (num uint64) { if bs == nil { //创建一个允许插入重复值的二叉搜 bs = New(true) @@ -110,10 +110,10 @@ func (bs *bsTree) Size() (num uint64) { // 以bsTree二叉搜索树做接收者 // 将该容器中所承载的元素清空 // 将该容器的size置0 -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param nil //@return nil -func (bs *bsTree) Clear() { +func (bs *BsTree) Clear() { if bs == nil { //创建一个允许插入重复值的二叉搜 bs = New(true) @@ -131,10 +131,10 @@ func (bs *bsTree) Clear() { // 如果含有元素则不为空,返回false // 如果不含有元素则说明为空,返回true // 如果容器不存在,返回true -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param nil //@return b bool 该容器是空的吗? -func (bs *bsTree) Empty() (b bool) { +func (bs *BsTree) Empty() (b bool) { if bs == nil { //创建一个允许插入重复值的二叉搜 bs = New(true) @@ -148,10 +148,10 @@ func (bs *bsTree) Empty() (b bool) { // 向二叉树插入元素e,若不允许重复则对相等元素进行覆盖 // 如果二叉树为空则之间用根节点承载元素e,否则以根节点开始进行查找 // 不做平衡 -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param e interface{} 待插入元素 //@return nil -func (bs *bsTree) Insert(e interface{}) { +func (bs *BsTree) Insert(e interface{}) { if bs == nil { //创建一个允许插入重复值的二叉搜 bs = New(true) @@ -185,10 +185,10 @@ func (bs *bsTree) Insert(e interface{}) { // 若允许重复记录则对承载元素e的节点中数量记录减一即可 // 若不允许重复记录则删除该节点同时将前缀节点或后继节点更换过来以保证二叉树的不发送断裂 // 如果该二叉树仅持有一个元素且根节点等价于待删除元素,则将二叉树根节点置为nil -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param e interface{} 待删除元素 //@return nil -func (bs *bsTree) Erase(e interface{}) { +func (bs *BsTree) Erase(e interface{}) { if bs == nil { //创建一个允许插入重复值的二叉搜 bs = New(true) @@ -219,10 +219,10 @@ func (bs *bsTree) Erase(e interface{}) { // 如果找到则返回该二叉树中和元素e相同元素的个数 // 如果不允许重复则最多返回1 // 如果未找到则返回0 -//@receiver bt *bsTree 接受者bsTree的指针 +//@receiver bt *BsTree 接受者bsTree的指针 //@param e interface{} 待查找元素 //@return num uint64 待查找元素在二叉树中存储的个数 -func (bs *bsTree) Count(e interface{}) (num uint64) { +func (bs *BsTree) Count(e interface{}) (num uint64) { if bs == nil { //二叉树不存在,返回0 return 0 diff --git a/goSTL/data_structure/deque/deque.go b/goSTL/data_structure/deque/deque.go index 2db4fe3..9575028 100644 --- a/goSTL/data_structure/deque/deque.go +++ b/goSTL/data_structure/deque/deque.go @@ -20,7 +20,7 @@ import ( //当一个节点全部被删除后则释放该节点,同时首尾节点做相应调整 //当添加节点时若未占满节点空间时移动下标并做覆盖即可 //当添加节点时空间已使用完毕时,根据添加位置新建一个新节点补充上去 -type deque struct { +type Deque struct { first *node //链表首节点指针 last *node //链表尾节点指针 size uint64 //当前存储的元素个数 @@ -38,8 +38,8 @@ type dequer interface { Empty() (b bool) //判断该双向队列是否为空 PushFront(e interface{}) //将元素e添加到该双向队列的首部 PushBack(e interface{}) //将元素e添加到该双向队列的尾部 - PopFront() //将该双向队列首元素弹出 - PopBack() //将该双向队列首元素弹出 + PopFront() (e interface{}) //将该双向队列首元素弹出 + PopBack() (e interface{}) //将该双向队列首元素弹出 Front() (e interface{}) //获取该双向队列首部元素 Back() (e interface{}) //获取该双向队列尾部元素 } @@ -51,9 +51,9 @@ type dequer interface { // 初始size为0 //@receiver nil //@param nil -//@return d *deque 新建的deque指针 -func New() *deque { - return &deque{ +//@return d *Deque 新建的deque指针 +func New() *Deque { + return &Deque{ first: nil, last: nil, size: 0, @@ -66,10 +66,10 @@ func New() *deque { // 以deque双向队列容器做接收者 // 将deque双向队列容器中所承载的元素放入迭代器中 // 节点的冗余空间不释放 -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (d *deque) Iterator() (i *Iterator.Iterator) { +func (d *Deque) Iterator() (i *Iterator.Iterator) { if d == nil { d = New() } @@ -87,10 +87,10 @@ func (d *deque) Iterator() (i *Iterator.Iterator) { // 返回该容器当前含有元素的数量 // 该长度并非实际占用空间数量 // 若容器为空则返回0 -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil //@return size uint64 容器中实际使用元素所占空间大小 -func (d *deque) Size() (size uint64) { +func (d *Deque) Size() (size uint64) { if d == nil { d = New() } @@ -102,10 +102,10 @@ func (d *deque) Size() (size uint64) { // 以deque双向队列容器做接收者 // 将该容器中所承载的元素清空 // 将该容器的首尾指针均置nil,将size重置为0 -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil //@return nil -func (d *deque) Clear() { +func (d *Deque) Clear() { if d == nil { d = New() return @@ -125,10 +125,10 @@ func (d *deque) Clear() { // 如果不含有元素则说明为空,返回true // 如果容器不存在,返回true // 该判断过程通过size进行判断,为0则为true,否则为false -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil //@return b bool 该容器是空的吗? -func (d *deque) Empty() (b bool) { +func (d *Deque) Empty() (b bool) { if d == nil { d = New() } @@ -140,10 +140,10 @@ func (d *deque) Empty() (b bool) { // 以deque双向队列向量容器做接收者 // 在容器首部插入元素 // 通过链表首节点进行添加 -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param e interface{} 待插入元素 //@return nil -func (d *deque) PushFront(e interface{}) { +func (d *Deque) PushFront(e interface{}) { if d == nil { d = New() } @@ -163,10 +163,10 @@ func (d *deque) PushFront(e interface{}) { // 以deque双向队列向量容器做接收者 // 在容器尾部插入元素 // 通过链表尾节点进行添加 -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param e interface{} 待插入元素 //@return nil -func (d *deque) PushBack(e interface{}) { +func (d *Deque) PushBack(e interface{}) { if d == nil { d = New() } @@ -186,19 +186,20 @@ func (d *deque) PushBack(e interface{}) { // 以deque双向队列容器做接收者 // 利用首节点进行弹出元素,可能存在首节点全部释放要进行首节点后移的情况 // 当元素全部删除后,释放全部空间,将首尾节点都设为nil -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil -//@return nil -func (d *deque) PopFront() { +//@return e interface{} 首元素 +func (d *Deque) PopFront() (e interface{}) { if d == nil { d = New() } if d.size == 0 { - return + return nil } d.mutex.Lock() //利用首节点删除首元素 //返回新的首节点 + e = d.first.front() d.first = d.first.popFront() d.size-- if d.size == 0 { @@ -207,6 +208,7 @@ func (d *deque) PopFront() { d.last = nil } d.mutex.Unlock() + return e } //@title PopBack @@ -214,20 +216,21 @@ func (d *deque) PopFront() { // 以deque双向队列容器做接收者 // 利用尾节点进行弹出元素,可能存在尾节点全部释放要进行尾节点前移的情况 // 当元素全部删除后,释放全部空间,将首尾节点都设为nil -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil -//@return nil -func (d *deque) PopBack() { +//@return e interface{} 尾元素 +func (d *Deque) PopBack() (e interface{}) { if d == nil { d = New() } if d.size == 0 { - return + return nil } d.mutex.Lock() //利用尾节点删除首元素 //返回新的尾节点 d.last = d.last.popBack() + e = d.last.back() d.size-- if d.size == 0 { //全部删除完成,释放空间,并将首尾节点设为nil @@ -235,6 +238,7 @@ func (d *deque) PopBack() { d.last = nil } d.mutex.Unlock() + return e } //@title Front @@ -242,10 +246,10 @@ func (d *deque) PopBack() { // 以deque双向队列容器做接收者 // 返回该容器的第一个元素,利用首节点进行寻找 // 若该容器当前为空,则返回nil -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil //@return e interface{} 容器的第一个元素 -func (d *deque) Front() (e interface{}) { +func (d *Deque) Front() (e interface{}) { if d == nil { d = New() } @@ -257,10 +261,10 @@ func (d *deque) Front() (e interface{}) { // 以deque双向队列容器做接收者 // 返回该容器的最后一个元素,利用尾节点进行寻找 // 若该容器当前为空,则返回nil -//@receiver d *deque 接收者的deque指针 +//@receiver d *Deque 接收者的deque指针 //@param nil //@return e interface{} 容器的最后一个元素 -func (d *deque) Back() (e interface{}) { +func (d *Deque) Back() (e interface{}) { if d == nil { d = New() } diff --git a/goSTL/data_structure/deque/deque_test.go b/goSTL/data_structure/deque/deque_test.go new file mode 100644 index 0000000..2a90eca --- /dev/null +++ b/goSTL/data_structure/deque/deque_test.go @@ -0,0 +1,36 @@ +package deque + +import ( + "reflect" + "sync" + "testing" +) + +func TestDeque_Front(t *testing.T) { + type fields struct { + first *node + last *node + size uint64 + mutex sync.Mutex + } + tests := []struct { + name string + fields fields + wantE interface{} + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d := &Deque{ + first: tt.fields.first, + last: tt.fields.last, + size: tt.fields.size, + mutex: tt.fields.mutex, + } + if gotE := d.Front(); !reflect.DeepEqual(gotE, tt.wantE) { + t.Errorf("Front() = %v, want %v", gotE, tt.wantE) + } + }) + } +} diff --git a/goSTL/data_structure/list/list.go b/goSTL/data_structure/list/list.go index b083c72..b83c2cd 100644 --- a/goSTL/data_structure/list/list.go +++ b/goSTL/data_structure/list/list.go @@ -21,7 +21,7 @@ import ( //当一个节点进行增删时需要同步修改其临接结点的前后指针 //结构体中记录整个链表的首尾指针,同时记录其当前已承载的元素 //使用并发控制锁以保证数据一致性 -type list struct { +type List struct { first *node //链表首节点指针 last *node //链表尾节点指针 size uint64 //当前存储的元素个数 @@ -53,9 +53,9 @@ type lister interface { // 初始size为0 //@receiver nil //@param nil -//@return l *list 新建的list指针 -func New() (l *list) { - return &list{ +//@return l *List 新建的list指针 +func New() (l *List) { + return &List{ first: nil, last: nil, size: 0, @@ -67,10 +67,10 @@ func New() (l *list) { //@description // 以list链表容器做接收者 // 将list链表容器中所承载的元素放入迭代器中 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (l *list) Iterator() (i *Iterator.Iterator) { +func (l *List) Iterator() (i *Iterator.Iterator) { if l == nil { l = New() } @@ -90,10 +90,10 @@ func (l *list) Iterator() (i *Iterator.Iterator) { // 以list链表容器做接收者 // 将list链表容器中所承载的元素利用比较器进行排序 // 可以自行传入比较函数,否则将调用默认比较函数 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param Cmp ...comparator.Comparator 比较函数 //@return nil -func (l *list) Sort(Cmp ...comparator.Comparator) { +func (l *List) Sort(Cmp ...comparator.Comparator) { if l == nil { l = New() } @@ -119,10 +119,10 @@ func (l *list) Sort(Cmp ...comparator.Comparator) { //@description // 以list链表容器做接收者 // 返回该容器当前含有元素的数量 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param nil //@return num int 容器中所承载的元素数量 -func (l *list) Size() (size uint64) { +func (l *List) Size() (size uint64) { if l == nil { l = New() } @@ -134,10 +134,10 @@ func (l *list) Size() (size uint64) { // 以list链表容器做接收者 // 将该容器中所承载的元素清空 // 将该容器的首尾指针均置nil,将size重置为0 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param nil //@return nil -func (l *list) Clear() { +func (l *List) Clear() { if l == nil { l = New() } @@ -157,10 +157,10 @@ func (l *list) Clear() { // 如果不含有元素则说明为空,返回true // 如果容器不存在,返回true // 该判断过程通过size进行判断,为0则为true,否则为false -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param nil //@return b bool 该容器是空的吗? -func (l *list) Empty() (b bool) { +func (l *List) Empty() (b bool) { if l == nil { l = New() } @@ -173,10 +173,10 @@ func (l *list) Empty() (b bool) { // 通过链表的首尾结点进行元素插入 // 插入的元素可以有很多个 // 通过判断idx -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param e interface{} 待插入元素 //@return nil -func (l *list) Insert(idx uint64, e interface{}) { +func (l *List) Insert(idx uint64, e interface{}) { if l == nil { l = New() } @@ -227,10 +227,10 @@ func (l *list) Insert(idx uint64, e interface{}) { // 当链表所承载的元素全部删除后则销毁链表 // 删除时通过idx与总元素数量选择从前或从后进行遍历以找到对应位置 // 删除后,将该位置的前后结点连接起来,以保证链表不断裂 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param idx uint64 被删除结点的下标(从0开始) //@return nil -func (l *list) Erase(idx uint64) { +func (l *List) Erase(idx uint64) { if l == nil { l = New() } @@ -276,10 +276,10 @@ func (l *list) Erase(idx uint64) { //@description // 以list链表容器做接收者 // 获取第idx位结点所承载的元素,若不在链表范围内则返回nil -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param idx uint64 被获取的结点位置(从0开始) //@return e interface{} 获取的元素 -func (l *list) Get(idx uint64) (e interface{}) { +func (l *List) Get(idx uint64) (e interface{}) { if l == nil { l = New() } @@ -310,11 +310,11 @@ func (l *list) Get(idx uint64) (e interface{}) { //@description // 以list链表容器做接收者 // 修改第idx为结点所承载的元素,超出范围则不修改 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param idx uint64 被修改的结点位置(从0开始) //@param e interface{} 修改后当元素 //@return nil -func (l *list) Set(idx uint64, e interface{}) { +func (l *List) Set(idx uint64, e interface{}) { if l == nil { l = New() } @@ -346,11 +346,11 @@ func (l *list) Set(idx uint64, e interface{}) { // 返回与e相同的元素的首个位置 // 可以自行传入用于判断相等的相等器进行处理 // 遍历从头至尾,如果不存在则返回l.size -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param e interface{} 要查找的元素 //@param Equ ...comparator.Equaler 相等器 //@param idx uint64 首下标 -func (l *list) IndexOf(e interface{}, Equ ...comparator.Equaler) (idx uint64) { +func (l *List) IndexOf(e interface{}, Equ ...comparator.Equaler) (idx uint64) { if l == nil { l = New() } @@ -378,11 +378,11 @@ func (l *list) IndexOf(e interface{}, Equ ...comparator.Equaler) (idx uint64) { // 以list链表容器做接收者 // 以begin为起点(包含),最多复制num个元素进入新链表 // 并返回新链表指针 -//@receiver l *list 接收者的list指针 +//@receiver l *List 接收者的list指针 //@param begin uint64 复制起点 //@param num uint64 复制个数上限 -//@param newList *list 新链表指针 -func (l *list) SubList(begin, num uint64) (newList *list) { +//@param newList *List 新链表指针 +func (l *List) SubList(begin, num uint64) (newList *List) { if l == nil { l = New() } diff --git a/goSTL/data_structure/priority_queue/priority_queue.go b/goSTL/data_structure/priority_queue/priority_queue.go index e0248f4..3455000 100644 --- a/goSTL/data_structure/priority_queue/priority_queue.go +++ b/goSTL/data_structure/priority_queue/priority_queue.go @@ -18,7 +18,7 @@ import ( //包含动态数组和比较器,同时包含其实际使用长度和实际占用空间容量 //该数据结构可以存储多个相同的元素,并不会产生冲突 //增删节点后会使用比较器保持该动态数组的相对有序性 -type priority_queue struct { +type Priority_queue struct { data []interface{} //动态数组 len uint64 //实际使用长度 cap uint64 //实际占用的空间的容量 @@ -46,8 +46,8 @@ type priority_queueer interface { // 如果不传入比较器,在后续的增删过程中将会去寻找默认比较器 //@receiver nil //@param Cmp ...comparator.Comparator priority_queue的比较器 -//@return pq *priority_queue 新建的priority_queue指针 -func New(cmps ...comparator.Comparator) (pq *priority_queue) { +//@return pq *Priority_queue 新建的priority_queue指针 +func New(cmps ...comparator.Comparator) (pq *Priority_queue) { var cmp comparator.Comparator if len(cmps) == 0 { cmp = nil @@ -55,7 +55,7 @@ func New(cmps ...comparator.Comparator) (pq *priority_queue) { cmp = cmps[0] } //比较器为nil时后续的增删将会去寻找默认比较器 - return &priority_queue{ + return &Priority_queue{ data: make([]interface{}, 1, 1), len: 0, cap: 1, @@ -68,10 +68,10 @@ func New(cmps ...comparator.Comparator) (pq *priority_queue) { //@description // 以priority_queue容器做接收者 // 返回该容器当前含有元素的数量 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param nil //@return num uint64 容器中存储元素的个数 -func (pq *priority_queue) Size() (num uint64) { +func (pq *Priority_queue) Size() (num uint64) { if pq == nil { pq = New() } @@ -82,10 +82,10 @@ func (pq *priority_queue) Size() (num uint64) { //@description // 以priority_queue容器做接收者 // 将该容器中所承载的元素清空 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param nil //@return nil -func (pq *priority_queue) Clear() { +func (pq *Priority_queue) Clear() { if pq == nil { pq = New() } @@ -105,10 +105,10 @@ func (pq *priority_queue) Clear() { // 如果不含有元素则说明为空,返回true // 如果容器不存在,返回true // 该判断过程通过含有元素个数进行判断 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param nil //@return b bool 该容器是空的吗? -func (pq *priority_queue) Empty() bool { +func (pq *Priority_queue) Empty() bool { if pq == nil { pq = New() } @@ -121,10 +121,10 @@ func (pq *priority_queue) Empty() bool { // 在该优先队列中插入元素e,利用比较器和交换使得优先队列保持相对有序状态 // 插入时,首先将该元素放入末尾,然后通过比较其逻辑上的父结点选择是否上移 // 扩容策略同vector,先进行翻倍扩容,在进行固定扩容,界限为2^16 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param e interface{} 待插入元素 //@return nil -func (pq *priority_queue) Push(e interface{}) { +func (pq *Priority_queue) Push(e interface{}) { if pq == nil { pq = New() } @@ -172,10 +172,10 @@ func (pq *priority_queue) Push(e interface{}) { // 以priority_queue容器做接收者 // 用于递归判断任意子结点和其父结点之间的关系,满足上升条件则递归上升 // 从而保证父节点必然都大于或都小于子节点 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param p uint64 待上升节点的位置 //@return nil -func (pq *priority_queue) up(p uint64) { +func (pq *Priority_queue) up(p uint64) { if p == 0 { //以及上升到顶部,直接结束即可 return @@ -194,10 +194,10 @@ func (pq *priority_queue) up(p uint64) { // 在该优先队列中删除顶部元素,利用比较器和交换使得优先队列保持相对有序状态 // 删除时首先将首结点移到最后一位进行交换,随后删除最后一位即可,然后对首节点进行下降即可 // 缩容时同vector一样,先进行固定缩容在进行折半缩容,界限为2^16 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param nil //@return nil -func (pq *priority_queue) Pop() { +func (pq *Priority_queue) Pop() { if pq == nil { pq = New() } @@ -238,10 +238,10 @@ func (pq *priority_queue) Pop() { // 以priority_queue容器做接收者 // 判断待下沉节点与其左右子节点的大小关系以确定是否进行递归上升 // 从而保证父节点必然都大于或都小于子节点 -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param p uint64 待下沉节点的位置 //@return nil -func (pq *priority_queue) down(p uint64) { +func (pq *Priority_queue) down(p uint64) { q := p //先判断其左结点是否在范围内,然后在判断左结点是否满足下降条件 if 2*p+1 <= pq.len-1 && pq.cmp(pq.data[p], pq.data[2*p+1]) > 0 { @@ -264,10 +264,10 @@ func (pq *priority_queue) down(p uint64) { // 以priority_queue容器做接收者 // 返回该优先队列容器的顶部元素 // 如果容器不存在或容器为空,返回nil -//@receiver pq *priority_queue 接受者priority_queue的指针 +//@receiver pq *Priority_queue 接受者priority_queue的指针 //@param nil //@return e interface{} 优先队列顶元素 -func (pq *priority_queue) Top() (e interface{}) { +func (pq *Priority_queue) Top() (e interface{}) { if pq == nil { pq = New() } diff --git a/goSTL/data_structure/queue/queue.go b/goSTL/data_structure/queue/queue.go index 38ea463..5389071 100644 --- a/goSTL/data_structure/queue/queue.go +++ b/goSTL/data_structure/queue/queue.go @@ -22,7 +22,7 @@ import ( //当添加节点时若未占满全部已分配空间则尾指针后移一位同时进行覆盖存放 //当添加节点时尾指针大于已分配空间长度,则先去掉首部多出来的空间,如果还不足则进行扩容 //首节点指针始终不能超过尾节点指针 -type queue struct { +type Queue struct { data []interface{} //泛型切片 begin uint64 //首节点下标 end uint64 //尾节点下标 @@ -52,9 +52,9 @@ type queuer interface { // 初始queue的首尾指针均置零 //@receiver nil //@param nil -//@return q *queue 新建的queue指针 -func New() (q *queue) { - return &queue{ +//@return q *Queue 新建的queue指针 +func New() (q *Queue) { + return &Queue{ data: make([]interface{}, 1, 1), begin: 0, end: 0, @@ -67,10 +67,10 @@ func New() (q *queue) { //@description // 以queue队列容器做接收者 // 将queue队列容器中不使用空间释放掉 -//@return q *queue 接收者的queue指针 +//@return q *Queue 接收者的queue指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (q *queue) Iterator() (i *Iterator.Iterator) { +func (q *Queue) Iterator() (i *Iterator.Iterator) { if q == nil { q = New() } @@ -88,10 +88,10 @@ func (q *queue) Iterator() (i *Iterator.Iterator) { // 返回该容器当前含有元素的数量 // 该长度并非实际占用空间数量 // 若容器为空则返回0 -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param nil -//@return size uint64 容器中实际使用元素所占空间大小 -func (q *queue) Size() (size uint64) { +//@return size uint64 容器中实际使用元素所占空间大小 +func (q *Queue) Size() (size uint64) { if q == nil { q = New() } @@ -103,10 +103,10 @@ func (q *queue) Size() (size uint64) { // 以queue队列容器做接收者 // 将该容器中所承载的元素清空 // 将该容器的首尾指针均置0,容量设为1 -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param nil //@return nil -func (q *queue) Clear() { +func (q *Queue) Clear() { if q == nil { q = New() } @@ -128,10 +128,10 @@ func (q *queue) Clear() { // 该判断过程通过首尾指针数值进行判断 // 当尾指针数值等于首指针时说明不含有元素 // 当尾指针数值大于首指针时说明含有元素 -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param nil //@return b bool 该容器是空的吗? -func (q *queue) Empty() (b bool) { +func (q *Queue) Empty() (b bool) { if q == nil { q = New() } @@ -145,10 +145,10 @@ func (q *queue) Empty() (b bool) { // 若尾指针小于切片实际使用长度,则对当前指针位置进行覆盖,同时尾下标后移一位 // 若尾指针等于切片实际使用长度,则对实际使用量和实际占用量进行判断 // 当首部还有冗余时则删将实际使用整体前移到首部,否则对尾部进行扩容即可 -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param e interface{} 待插入元素 //@return nil -func (q *queue) Push(e interface{}) { +func (q *Queue) Push(e interface{}) { if q == nil { q = New() } @@ -198,10 +198,10 @@ func (q *queue) Push(e interface{}) { // 所以可以对首部预留2^10的冗余,当超过时直接对首部冗余清除即可,释放首部空间时尾部空间仍然保留不变 // 当首部冗余不足2^10时,但冗余超过实际使用空间,也会对首部进行缩容,尾部不变 // 同时返回队首元素 -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param nil //@return e interface{} 队首元素 -func (q *queue) Pop() (e interface{}) { +func (q *Queue) Pop() (e interface{}) { if q == nil { q = New() return nil @@ -231,10 +231,10 @@ func (q *queue) Pop() (e interface{}) { // 以queue队列容器做接收者 // 返回该容器的第一个元素 // 若该容器当前为空,则返回nil -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param nil //@return e interface{} 容器的第一个元素 -func (q *queue) Front() (e interface{}) { +func (q *Queue) Front() (e interface{}) { if q == nil { q = New() return nil @@ -251,10 +251,10 @@ func (q *queue) Front() (e interface{}) { // 以queue队列容器做接收者 // 返回该容器的最后一个元素 // 若该容器当前为空,则返回nil -//@receiver q *queue 接受者queue的指针 +//@receiver q *Queue 接受者queue的指针 //@param nil //@return e interface{} 容器的最后一个元素 -func (q *queue) Back() (e interface{}) { +func (q *Queue) Back() (e interface{}) { if q == nil { q = New() return nil diff --git a/goSTL/data_structure/ring/ring.go b/goSTL/data_structure/ring/ring.go index b8ff088..c8b9b58 100644 --- a/goSTL/data_structure/ring/ring.go +++ b/goSTL/data_structure/ring/ring.go @@ -22,7 +22,7 @@ import ( //结构体中记录该环中当前所持有的结点的指针即可 //同时记录该环中存在多少元素即size //使用并发控制锁以保证数据一致性 -type ring struct { +type Ring struct { now *node //环当前持有的结点指针 size uint64 //当前存储的元素个数 mutex sync.Mutex //并发控制锁 @@ -52,9 +52,9 @@ type ringer interface { // 初始size为0 //@receiver nil //@param nil -//@return r *ring 新建的ring指针 -func New() (r *ring) { - return &ring{ +//@return r *Ring 新建的ring指针 +func New() (r *Ring) { + return &Ring{ now: nil, size: 0, mutex: sync.Mutex{}, @@ -66,10 +66,10 @@ func New() (r *ring) { // 以ring环容器做接收者 // 将ring环容器中所承载的元素放入迭代器中 // 从该结点开始向后遍历获取全部承载的元素 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (r *ring) Iterator() (i *Iterator.Iterator) { +func (r *Ring) Iterator() (i *Iterator.Iterator) { if r == nil { r = New() } @@ -89,10 +89,10 @@ func (r *ring) Iterator() (i *Iterator.Iterator) { //@description // 以ring环容器做接收者 // 返回该容器当前含有元素的数量 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return num int 容器中所承载的元素数量 -func (r *ring) Size() (size uint64) { +func (r *Ring) Size() (size uint64) { if r == nil { r = New() } @@ -104,10 +104,10 @@ func (r *ring) Size() (size uint64) { // 以ring环容器做接收者 // 将该容器中所承载的元素清空 // 将该容器的当前持有的结点置为nil,长度初始为0 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return nil -func (r *ring) Clear() { +func (r *Ring) Clear() { if r == nil { r = New() } @@ -123,10 +123,10 @@ func (r *ring) Clear() { // 以ring环容器做接收者 // 判断该ring环容器是否含有元素 // 该判断过程通过size进行判断,size为0则为true,否则为false -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return b bool 该容器是空的吗? -func (r *ring) Empty() (b bool) { +func (r *Ring) Empty() (b bool) { if r == nil { r = New() } @@ -139,10 +139,10 @@ func (r *ring) Empty() (b bool) { // 通过环中当前持有的结点进行添加 // 如果环为建立,则新建一个自环结点设为环 // 存在持有的结点,则在其后方添加即可 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param e interface{} 待插入元素 //@return nil -func (r *ring) Insert(e interface{}) { +func (r *Ring) Insert(e interface{}) { if r == nil { r = New() } @@ -166,10 +166,10 @@ func (r *ring) Insert(e interface{}) { // 先判断是否仅持有一个结点 // 若仅有一个结点,则直接销毁环 // 否则将当前持有结点设为下一节点,并前插原持有结点的前结点即可 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return nil -func (r *ring) Erase() { +func (r *Ring) Erase() { if r == nil { r = New() } @@ -196,10 +196,10 @@ func (r *ring) Erase() { // 以ring环容器做接收者 // 获取环中当前持有节点所承载的元素 // 若环中持有的结点不存在,直接返回nil -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return e interface{} 获取的元素 -func (r *ring) Value() (e interface{}) { +func (r *Ring) Value() (e interface{}) { if r == nil { r = New() } @@ -215,10 +215,10 @@ func (r *ring) Value() (e interface{}) { // 以ring环容器做接收者 // 修改当前持有结点所承载的元素 // 若未持有结点,直接结束即可 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param e interface{} 修改后当元素 //@return nil -func (r *ring) Set(e interface{}) { +func (r *Ring) Set(e interface{}) { if r == nil { r = New() } @@ -235,10 +235,10 @@ func (r *ring) Set(e interface{}) { // 以ring环容器做接收者 // 将当前持有的结点后移一位 // 若当前无持有结点,则直接结束 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return nil -func (r *ring) Next() { +func (r *Ring) Next() { if r == nil { r = New() } @@ -255,10 +255,10 @@ func (r *ring) Next() { // 以ring环容器做接收者 // 将当前持有的结点前移一位 // 若当前无持有结点,则直接结束 -//@receiver r *ring 接收者的ring指针 +//@receiver r *Ring 接收者的ring指针 //@param nil //@return nil -func (r *ring) Pre() { +func (r *Ring) Pre() { if r == nil { r = New() } diff --git a/goSTL/data_structure/stack/stack.go b/goSTL/data_structure/stack/stack.go index 4049435..5fa6666 100644 --- a/goSTL/data_structure/stack/stack.go +++ b/goSTL/data_structure/stack/stack.go @@ -20,7 +20,7 @@ import ( //当冗余空间不足时先倍增空间至2^16,超过后每次增加2^16的空间 //删除结点后如果冗余超过2^16,则释放掉 //删除后若冗余量超过使用量,也释放掉冗余空间 -type stack struct { +type Stack struct { data []interface{} //用于存储元素的动态数组 top uint64 //顶部指针 cap uint64 //动态数组的实际空间 @@ -47,9 +47,9 @@ type stacker interface { // 初始stack的顶部指针置0,容量置1 //@receiver nil //@param nil -//@return s *stack 新建的stack指针 -func New() (s *stack) { - return &stack{ +//@return s *Stack 新建的stack指针 +func New() (s *Stack) { + return &Stack{ data: make([]interface{}, 1, 1), top: 0, cap: 1, @@ -62,10 +62,10 @@ func New() (s *stack) { // 以stack栈容器做接收者 // 将stack栈容器中不使用空间释放掉 // 返回一个包含容器中所有使用元素的迭代器 -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (s *stack) Iterator() (i *Iterator.Iterator) { +func (s *Stack) Iterator() (i *Iterator.Iterator) { if s == nil { s = New() } @@ -91,10 +91,10 @@ func (s *stack) Iterator() (i *Iterator.Iterator) { //@description // 以stack栈容器做接收者 // 返回该容器当前含有元素的数量 -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param nil //@return num int 容器中实际使用元素所占空间大小 -func (s *stack) Size() (num uint64) { +func (s *Stack) Size() (num uint64) { if s == nil { s = New() } @@ -106,10 +106,10 @@ func (s *stack) Size() (num uint64) { // 以stack栈容器做接收者 // 将该容器中所承载的元素清空 // 将该容器的尾指针置0 -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param nil //@return nil -func (s *stack) Clear() { +func (s *Stack) Clear() { if s == nil { s = New() } @@ -130,10 +130,10 @@ func (s *stack) Clear() { // 该判断过程通过顶部指针数值进行判断 // 当顶部指针数值为0时说明不含有元素 // 当顶部指针数值大于0时说明含有元素 -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param nil //@return b bool 该容器是空的吗? -func (s *stack) Empty() (b bool) { +func (s *Stack) Empty() (b bool) { if s == nil { return true } @@ -146,10 +146,10 @@ func (s *stack) Empty() (b bool) { // 在容器顶部插入元素 // 若存储冗余空间,则在顶部指针位插入元素,随后上移顶部指针 // 否则进行扩容,扩容后获得冗余空间重复上一步即可。 -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param e interface{} 待插入顶部的元素 //@return nil -func (s *stack) Push(e interface{}) { +func (s *Stack) Push(e interface{}) { if s == nil { s = New() } @@ -185,10 +185,10 @@ func (s *stack) Push(e interface{}) { // 弹出容器顶部元素,同时顶部指针下移一位 // 当顶部指针小于容器切片实际使用空间的一半时,重新分配空间释放未使用部分 // 若容器为空,则不进行弹出 -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param nil //@return nil -func (s *stack) Pop() { +func (s *Stack) Pop() { if s == nil { s = New() return @@ -219,10 +219,10 @@ func (s *stack) Pop() { // 以stack栈容器做接收者 // 返回该容器的顶部元素 // 若该容器当前为空,则返回nil -//@receiver s *stack 接受者stack的指针 +//@receiver s *Stack 接受者stack的指针 //@param nil //@return e interface{} 容器的顶部元素 -func (s *stack) Top() (e interface{}) { +func (s *Stack) Top() (e interface{}) { if s == nil { return nil } diff --git a/goSTL/data_structure/treap/node.go b/goSTL/data_structure/treap/node.go new file mode 100644 index 0000000..d1ad26d --- /dev/null +++ b/goSTL/data_structure/treap/node.go @@ -0,0 +1,304 @@ +package treap +//@Title Treap +//@Description +// 树堆的节点 +// 节点在创建是赋予一个随机的优先级,随后进行堆平衡,使得整个树堆依概率实现平衡 +// 可通过节点实现树堆的添加删除 +// 也可通过节点返回整个二叉搜索树的所有元素 +import ( + "github.com/hlccd/goSTL/utils/comparator" + "math/rand" +) + +//node树节点结构体 +//该节点是树堆的树节点 +//若该树堆允许重复则对节点num+1即可,否则对value进行覆盖 +//树堆节点将针对堆的性质通过左右旋转的方式做平衡 +type node struct { + value interface{} //节点中存储的元素 + priority uint16 //该节点的优先级,随机生成 + num int //该节点中存储的数量 + left *node //左节点指针 + right *node //右节点指针 +} + +//@title newNode +//@description +// 新建一个树堆节点并返回 +// 将传入的元素e作为该节点的承载元素 +// 该节点的num默认为1,左右子节点设为nil +// 该节点优先级随机生成,范围在0~2^16内 +//@receiver nil +//@param e interface{} 承载元素e +//@param rand *rand.Rand 随机数生成器 +//@return n *node 新建的树堆树节点的指针 +func newNode(e interface{}, rand *rand.Rand) (n *node) { + return &node{ + value: e, + priority: uint16(rand.Intn(65535)), + num: 1, + left: nil, + right: nil, + } +} + +//@title inOrder +//@description +// 以node树堆节点做接收者 +// 以中缀序列返回节点集合 +// 若允许重复存储则对于重复元素进行多次放入 +//@receiver n *node 接受者node的指针 +//@param nil +//@return es []interface{} 以该节点为起点的中缀序列 +func (n *node) inOrder() (es []interface{}) { + if n == nil { + return es + } + if n.left != nil { + es = append(es, n.left.inOrder()...) + } + for i := 0; i < n.num; i++ { + es = append(es, n.value) + } + if n.right != nil { + es = append(es, n.right.inOrder()...) + } + return es +} + + +//@title rightRotate +//@description +// 以node树堆节点做接收者 +// 新建一个节点作为n节点的右节点,同时将n节点的数值放入新建节点中作为右转后的n节点 +// 右转后的n节点的左节点是原n节点左节点的右节点,右转后的右节点保持不变 +// 原n节点改为原n节点的左节点,同时右节点指向新建的节点即右转后的n节点 +// 该右转方式可以保证n节点的双亲节点不用更换节点指向 +//@receiver n *node 接受者node的指针 +//@param nil +//@return nil +func (n *node) rightRotate() { + if n == nil { + return + } + if n.left == nil { + return + } + //新建节点作为更换后的n节点 + tmp := &node{ + value: n.value, + priority: n.priority, + num: n.num, + left: n.left.right, + right: n.right, + } + //原n节点左节点上移到n节点位置 + n.right = tmp + n.value = n.left.value + n.priority = n.left.priority + n.num = n.left.num + n.left = n.left.left +} + +//@title leftRotate +//@description +// 以node树堆节点做接收者 +// 新建一个节点作为n节点的左节点,同时将n节点的数值放入新建节点中作为左转后的n节点 +// 左转后的n节点的右节点是原n节点右节点的左节点,左转后的左节点保持不变 +// 原n节点改为原n节点的右节点,同时左节点指向新建的节点即左转后的n节点 +// 该左转方式可以保证n节点的双亲节点不用更换节点指向 +//@receiver n *node 接受者node的指针 +//@param nil +//@return nil +func (n *node) leftRotate() { + if n == nil { + return + } + if n.right == nil { + return + } + //新建节点作为更换后的n节点 + tmp := &node{ + value: n.value, + priority: n.priority, + num: n.num, + left: n.left, + right: n.right.left, + } + //原n节点右节点上移到n节点位置 + n.left = tmp + n.value = n.right.value + n.priority = n.right.priority + n.num = n.right.num + n.right = n.right.right +} + +//@title insert +//@description +// 以node二叉搜索树节点做接收者 +// 从n节点中插入元素e +// 如果n节点中承载元素与e不同则根据大小从左右子树插入该元素 +// 如果n节点与该元素相等,且允许重复值,则将num+1否则对value进行覆盖 +// 插入成功返回true,插入失败或不允许重复插入返回false +//@receiver n *node 接受者node的指针 +//@param e interface{} 待插入元素 +//@param isMulti bool 是否允许重复? +//@param cmp comparator.Comparator 判断大小的比较器 +//@return b bool 是否插入成功? +func (n *node) insert(e *node, isMulti bool, cmp comparator.Comparator) (b bool) { + if cmp(n.value, e.value) > 0 { + if n.left == nil { + //将左节点直接设为e + n.left = e + b = true + } else { + //对左节点进行递归插入 + b = n.left.insert(e, isMulti, cmp) + } + if n.priority > e.priority { + //对n节点进行右转 + n.rightRotate() + } + return b + } else if cmp(n.value, e.value) < 0 { + if n.right == nil { + //将右节点直接设为e + n.right = e + b = true + } else { + //对右节点进行递归插入 + b = n.right.insert(e, isMulti, cmp) + } + if n.priority > e.priority { + //对n节点进行左转 + n.leftRotate() + } + return b + } + if isMulti { + //允许重复 + n.num++ + return true + } + //不允许重复,对值进行覆盖 + n.value = e.value + return false +} + +//@title delete +//@description +// 以node二叉搜索树节点做接收者 +// 从n节点中删除元素e +// 如果n节点中承载元素与e不同则根据大小从左右子树删除该元素 +// 如果n节点与该元素相等,且允许重复值,则将num-1否则直接删除该元素 +// 删除时先寻找该元素的前缀节点,若不存在则寻找其后继节点进行替换 +// 替换后删除该节点 +//@receiver n *node 接受者node的指针 +//@param e interface{} 待删除元素 +//@param isMulti bool 是否允许重复? +//@param cmp comparator.Comparator 判断大小的比较器 +//@return b bool 是否删除成功? +func (n *node) delete(e interface{}, isMulti bool, cmp comparator.Comparator) (b bool) { + if n == nil { + return false + } + //n中承载元素小于e,从右子树继续删除 + if cmp(n.value, e) < 0 { + if n.right == nil { + //右子树为nil,删除终止 + return false + } + if cmp(e, n.right.value) == 0 && (!isMulti || n.right.num == 1) { + //待删除节点无子节点,直接删除即可 + if n.right.left == nil && n.right.right == nil { + //右子树可直接删除 + n.right = nil + return true + } + } + //从右子树继续删除 + return n.right.delete(e, isMulti, cmp) + } + //n中承载元素大于e,从左子树继续删除 + if cmp(n.value, e) > 0 { + if n.left == nil { + //左子树为nil,删除终止 + return false + } + if cmp(e, n.left.value) == 0 && (!isMulti || n.left.num == 1) { + //待删除节点无子节点,直接删除即可 + if n.left.left == nil && n.left.right == nil { + //左子树可直接删除 + n.left = nil + return true + } + } + //从左子树继续删除 + return n.left.delete(e, isMulti, cmp) + } + if isMulti && n.num > 1 { + //允许重复且数量超过1 + n.num-- + return true + } + //删除该节点 + tmp := n + //左右子节点都存在则选择优先级较小一个进行旋转 + for tmp.left != nil && tmp.right != nil { + if tmp.left.priority < tmp.right.priority { + tmp.rightRotate() + if tmp.right.left == nil && tmp.right.right == nil { + tmp.right = nil + return false + } + tmp = tmp.right + } else { + tmp.leftRotate() + if tmp.left.left == nil && tmp.left.right == nil { + tmp.left = nil + return false + } + tmp = tmp.left + } + } + if tmp.left == nil && tmp.right != nil { + //到左子树为nil时直接换为右子树即可 + tmp.value = tmp.right.value + tmp.num = tmp.right.num + tmp.priority = tmp.right.priority + tmp.left = tmp.right.left + tmp.right = tmp.right.right + } else if tmp.right == nil && tmp.left != nil { + //到右子树为nil时直接换为左子树即可 + tmp.value = tmp.left.value + tmp.num = tmp.left.num + tmp.priority = tmp.left.priority + tmp.right = tmp.left.right + tmp.left = tmp.left.left + } + //当左右子树都为nil时直接结束 + return true +} + +//@title search +//@description +// 以node二叉搜索树节点做接收者 +// 从n节点中查找元素e并返回存储的个数 +// 如果n节点中承载元素与e不同则根据大小从左右子树查找该元素 +// 如果n节点与该元素相等,则直接返回其个数 +//@receiver n *node 接受者node的指针 +//@param e interface{} 待查找元素 +//@param isMulti bool 是否允许重复? +//@param cmp comparator.Comparator 判断大小的比较器 +//@return num int 待查找元素在二叉树中存储的数量 +func (n *node) search(e interface{}, cmp comparator.Comparator) (num int) { + if n == nil { + return 0 + } + if cmp(n.value, e) > 0 { + return n.left.search(e, cmp) + } else if cmp(n.value, e) < 0 { + return n.right.search(e, cmp) + } + return n.num +} \ No newline at end of file diff --git a/goSTL/data_structure/treap/treap.go b/goSTL/data_structure/treap/treap.go new file mode 100644 index 0000000..e2ca20f --- /dev/null +++ b/goSTL/data_structure/treap/treap.go @@ -0,0 +1,242 @@ +package treap + +//@Title treap +//@Description +// Treap树堆容器包 +// 树堆本身是一个二叉树,同时赋予随机的节点优先级 +// 通过旋转使树堆中节点既满足存储元素的组成符合二叉搜索树的性质,同时也使得优先级满足堆的的性质 +// 同时由于每个节点的优先级随机生成,使得整个二叉树得以实现随机平衡 +// 该树堆依概率实现平衡 +// 可接纳不同类型的元素,但建议在同一个树堆中使用相同类型的元素 +// 配合比较器实现元素之间的大小比较 + +import ( + "github.com/hlccd/goSTL/utils/comparator" + "github.com/hlccd/goSTL/utils/iterator" + "math/rand" + "sync" + "time" +) + +//treap树堆结构体 +//该实例存储树堆的根节点 +//同时保存该树堆中已经存储了多少个元素 +//二叉树中排序使用的比较器在创建时传入,若不传入则在插入首个节点时从默认比较器中寻找 +//该树堆实例中存储随机数生成器,用于后续新建节点时生成随机数 +//创建时传入是否允许该树堆出现重复值,如果不允许则进行覆盖,允许则对节点数目增加即可 +type treap struct { + root *node //根节点指针 + size int //存储元素数量 + cmp comparator.Comparator //比较器 + rand *rand.Rand //随机数生成器 + isMulti bool //是否允许重复 + mutex sync.Mutex //并发控制锁 +} + +//treap树堆容器接口 +//存放了treap树堆可使用的函数 +//对应函数介绍见下方 +type treaper interface { + Iterator() (i *Iterator.Iterator) //返回包含该树堆的所有元素,重复则返回多个 + Size() (num int) //返回该树堆中保存的元素个数 + Clear() //清空该树堆 + Empty() (b bool) //判断该树堆是否为空 + Insert(e interface{}) //向树堆中插入元素e + Erase(e interface{}) //从树堆中删除元素e + Count(e interface{}) (num int) //从树堆中寻找元素e并返回其个数 +} + +//@title New +//@description +// 新建一个treap树堆容器并返回 +// 初始根节点为nil +// 传入该树堆是否为可重复属性,如果为true则保存重复值,否则对原有相等元素进行覆盖 +// 若有传入的比较器,则将传入的第一个比较器设为该树堆的比较器 +//@receiver nil +//@param isMulti bool 该树堆是否保存重复值? +//@param Cmp ...comparator.Comparator treap比较器集 +//@return t *treap 新建的treap指针 +func New(isMulti bool, Cmp ...comparator.Comparator) (t *treap) { + //设置默认比较器 + var cmp comparator.Comparator + if len(Cmp) > 0 { + cmp = Cmp[0] + } + //创建随机数生成器 + r := rand.New(rand.NewSource(time.Now().UnixNano())) + return &treap{ + root: nil, + size: 0, + cmp: cmp, + rand: r, + isMulti: isMulti, + mutex: sync.Mutex{}, + } +} + +//@title Iterator +//@description +// 以treap树堆做接收者 +// 将该树堆中所有保存的元素将从根节点开始以中缀序列的形式放入迭代器中 +// 若允许重复存储则对于重复元素进行多次放入 +//@receiver t *treap 接受者treap的指针 +//@param nil +//@return i *iterator.Iterator 新建的Iterator迭代器指针 +func (t *treap) Iterator() (i *Iterator.Iterator) { + if t == nil { + return nil + } + t.mutex.Lock() + es := t.root.inOrder() + i = Iterator.New(&es) + t.mutex.Unlock() + return i +} + +//@title Size +//@description +// 以treap树堆做接收者 +// 返回该容器当前含有元素的数量 +// 如果容器为nil返回0 +//@receiver t *treap 接受者treap的指针 +//@param nil +//@return num int 容器中实际使用元素所占空间大小 +func (t *treap) Size() (num int) { + if t == nil { + return 0 + } + return t.size +} +//@title Clear +//@description +// 以treap树堆做接收者 +// 将该容器中所承载的元素清空 +// 将该容器的size置0 +//@receiver t *treap 接受者treap的指针 +//@param nil +//@return nil +func (t *treap) Clear() { + if t == nil { + return + } + t.mutex.Lock() + t.root = nil + t.size = 0 + t.mutex.Unlock() +} +//@title Empty +//@description +// 以treap树堆做接收者 +// 判断该二叉搜索树是否含有元素 +// 如果含有元素则不为空,返回false +// 如果不含有元素则说明为空,返回true +// 如果容器不存在,返回true +//@receiver t *treap 接受者treap的指针 +//@param nil +//@return b bool 该容器是空的吗? +func (t *treap) Empty() (b bool) { + if t == nil { + return true + } + if t.size > 0 { + return false + } + return true +} + +//@title Insert +//@description +// 以treap树堆做接收者 +// 向二叉树插入元素e,若不允许重复则对相等元素进行覆盖 +// 如果二叉树为空则之间用根节点承载元素e,否则以根节点开始进行查找 +// 对于该树堆来说,通过赋予随机的优先级根据堆的性质来实现平衡 +//@receiver t *treap 接受者treap的指针 +//@param e interface{} 待插入元素 +//@return nil +func (t *treap) Insert(e interface{}) { + //判断容器是否存在 + if t == nil { + return + } + t.mutex.Lock() + if t.Empty() { + //判断比较器是否存在 + if t.cmp == nil { + t.cmp = comparator.GetCmp(e) + } + if t.cmp == nil { + t.mutex.Unlock() + return + } + //插入到根节点 + t.root = newNode(e, t.rand) + t.size = 1 + t.mutex.Unlock() + return + } + //从根节点向下插入 + if t.root.insert(newNode(e, t.rand), t.isMulti, t.cmp) { + t.size++ + } + t.mutex.Unlock() +} + + +//@title Erase +//@description +// 以treap树堆做接收者 +// 从树堆中删除元素e +// 若允许重复记录则对承载元素e的节点中数量记录减一即可 +// 若不允许重复记录则删除该节点同时将前缀节点或后继节点更换过来以保证树堆的不发送断裂 +// 交换后根据优先级进行左右旋转以保证符合堆的性质 +// 如果该树堆仅持有一个元素且根节点等价于待删除元素,则将根节点置为nil +//@receiver t *treap 接受者treap的指针 +//@param e interface{} 待删除元素 +//@return nil +func (t *treap) Erase(e interface{}) { + if t == nil { + return + } + if t.Empty() { + return + } + t.mutex.Lock() + if t.size == 1 && t.cmp(t.root.value, e) == 0 { + //该树堆仅持有一个元素且根节点等价于待删除元素,则将根节点置为nil + t.root = nil + t.size = 0 + t.mutex.Unlock() + return + } + //从根节点开始删除元素 + if t.root.delete(e, t.isMulti, t.cmp) { + //删除成功 + t.size-- + } + t.mutex.Unlock() +} + +//@title Count +//@description +// 以treap树堆做接收者 +// 从树堆中查找元素e的个数 +// 如果找到则返回该树堆中和元素e相同元素的个数 +// 如果不允许重复则最多返回1 +// 如果未找到则返回0 +//@receiver t *treap 接受者treap的指针 +//@param e interface{} 待查找元素 +//@return num int 待查找元素在树堆中存储的个数 +func (t *treap) Count(e interface{}) (num int) { + if t == nil { + //树堆不存在,直接返回0 + return 0 + } + if t.Empty() { + return + } + t.mutex.Lock() + num = t.root.search(e, t.cmp) + t.mutex.Unlock() + //树堆存在,从根节点开始查找该元素 + return num +} \ No newline at end of file diff --git a/goSTL/data_structure/vector/vector.go b/goSTL/data_structure/vector/vector.go index 321fa3b..8abb29d 100644 --- a/goSTL/data_structure/vector/vector.go +++ b/goSTL/data_structure/vector/vector.go @@ -25,7 +25,7 @@ import ( //并发控制锁用以保证在高并发过程中不会出现错误 //使用比较器重载了Sort -type vector struct { +type Vector struct { data []interface{} //动态数组 len uint64 //当前已用数量 cap uint64 //可容纳元素数量 @@ -59,9 +59,9 @@ type vectorer interface { // 初始vector的长度为0,容量为1 //@receiver nil //@param nil -//@return v *vector 新建的vector指针 -func New() (v *vector) { - return &vector{ +//@return v *Vector 新建的vector指针 +func New() (v *Vector) { + return &Vector{ data: make([]interface{}, 1, 1), len: 0, cap: 1, @@ -74,10 +74,10 @@ func New() (v *vector) { // 以vector向量容器做接收者 // 释放未使用的空间,并将已使用的部分用于创建迭代器 // 返回一个包含容器中所有使用元素的迭代器 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return i *iterator.Iterator 新建的Iterator迭代器指针 -func (v *vector) Iterator() (i *Iterator.Iterator) { +func (v *Vector) Iterator() (i *Iterator.Iterator) { if v == nil { v = New() } @@ -104,10 +104,10 @@ func (v *vector) Iterator() (i *Iterator.Iterator) { // 以vector向量容器做接收者 // 将vector向量容器中不使用空间释放掉 // 对元素中剩余的部分进行排序 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param Cmp ...comparator.Comparator 比较函数 //@return nil -func (v *vector) Sort(Cmp ...comparator.Comparator) { +func (v *Vector) Sort(Cmp ...comparator.Comparator) { if v == nil { v = New() } @@ -138,10 +138,10 @@ func (v *vector) Sort(Cmp ...comparator.Comparator) { // 以vector向量容器做接收者 // 返回该容器当前含有元素的数量 // 该长度并非实际占用空间数量,而是实际使用空间 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return num int 容器中实际使用元素所占空间大小 -func (v *vector) Size() (num uint64) { +func (v *Vector) Size() (num uint64) { if v == nil { v = New() } @@ -152,10 +152,10 @@ func (v *vector) Size() (num uint64) { //@description // 以vector向量容器做接收者 // 将该容器中的动态数组重置,所承载的元素清空 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return nil -func (v *vector) Clear() { +func (v *Vector) Clear() { if v == nil { v = New() } @@ -176,10 +176,10 @@ func (v *vector) Clear() { // 该判断过程通过长度进行判断 // 当长度为0时说明不含有元素 // 当长度大于0时说明含有元素 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return b bool 该容器是空的吗? -func (v *vector) Empty() (b bool) { +func (v *Vector) Empty() (b bool) { if v == nil { v = New() } @@ -193,10 +193,10 @@ func (v *vector) Empty() (b bool) { // 若长度小于容量时,则对以长度为下标的位置进行覆盖,同时len++ // 若长度等于容量时,需要进行扩容 // 对于扩容而言,当容量小于2^16时,直接将容量翻倍,否则将容量增加2^16 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param e interface{} 待插入元素 //@return nil -func (v *vector) PushBack(e interface{}) { +func (v *Vector) PushBack(e interface{}) { if v == nil { v = New() } @@ -234,10 +234,10 @@ func (v *vector) PushBack(e interface{}) { // 当弹出元素后,可能进行缩容 // 当容量和实际使用差值超过2^16时,容量直接减去2^16 // 否则,当实际使用长度是容量的一半时,进行折半缩容 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return nil -func (v *vector) PopBack() { +func (v *Vector) PopBack() { if v == nil { v = New() } @@ -271,11 +271,11 @@ func (v *vector) PopBack() { // 否则在切片中间第idx位插入元素,同时后移第idx位以后的元素 // 根据冗余量选择是否扩容,扩容策略同上 // 插入后len++ -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param idx uint64 待插入节点的位置(下标从0开始) //@param e interface{} 待插入元素 //@return nil -func (v *vector) Insert(idx uint64, e interface{}) { +func (v *Vector) Insert(idx uint64, e interface{}) { if v == nil { v = New() } @@ -317,10 +317,10 @@ func (v *vector) Insert(idx uint64, e interface{}) { // 否则在切片中间第idx位删除元素,同时前移第idx位以后的元素 // 长度同步-- // 进行缩容判断,缩容策略同上 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param idx uint64 待删除节点的位置(下标从0开始) //@return nil -func (v *vector) Erase(idx uint64) { +func (v *Vector) Erase(idx uint64) { if v == nil { v = New() } @@ -353,10 +353,10 @@ func (v *vector) Erase(idx uint64) { // 以vector向量容器做接收者 // 将vector容器中不使用空间释放掉 // 将该容器中的泛型切片中的所有元素顺序逆转 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return nil -func (v *vector) Reverse() { +func (v *Vector) Reverse() { if v == nil { v = New() } @@ -386,10 +386,10 @@ func (v *vector) Reverse() { // 当idx不在容器中泛型切片的使用范围内 // 即当idx小于0或者idx大于容器所含有的元素个数时返回nil // 反之返回对应位置的元素 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param idx uint64 待查找元素的位置(下标从0开始) //@return e interface{} 从容器中查找的第idx位元素 -func (v *vector) At(idx uint64) (e interface{}) { +func (v *Vector) At(idx uint64) (e interface{}) { if v == nil { v=New() return nil @@ -413,10 +413,10 @@ func (v *vector) At(idx uint64) (e interface{}) { // 以vector向量容器做接收者 // 返回该容器的第一个元素 // 若该容器当前为空,则返回nil -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return e interface{} 容器的第一个元素 -func (v *vector) Front() (e interface{}) { +func (v *Vector) Front() (e interface{}) { if v == nil { v=New() return nil @@ -436,11 +436,10 @@ func (v *vector) Front() (e interface{}) { // 以vector向量容器做接收者 // 返回该容器的最后一个元素 // 若该容器当前为空,则返回nil -//@auth hlccd 2021-07-4 -//@receiver v *vector 接受者vector的指针 +//@receiver v *Vector 接受者vector的指针 //@param nil //@return e interface{} 容器的最后一个元素 -func (v *vector) Back() (e interface{}) { +func (v *Vector) Back() (e interface{}) { if v == nil { v=New() return nil