From cf30b4eb4c911d7c48afdfdc3cdde5de1c298243 Mon Sep 17 00:00:00 2001 From: charlie <3140647@qq.com> Date: Fri, 18 Nov 2022 16:56:56 +0800 Subject: [PATCH] collection --- collections/deque/deque.go | 15 ++++++ collections/deque/deque_test.go | 1 + collections/queue/queue.go | 35 +++++++++++++ collections/queue/queue_test.go | 1 + collections/rbtree/rbtree.go | 1 + collections/rbtree/rbtree_test.go | 1 + collections/stack/stack.go | 81 +++++++++++++++++++++++++++++++ collections/stack/stack_test.go | 24 +++++++++ 8 files changed, 159 insertions(+) create mode 100644 collections/deque/deque.go create mode 100644 collections/deque/deque_test.go create mode 100644 collections/queue/queue.go create mode 100644 collections/queue/queue_test.go create mode 100644 collections/rbtree/rbtree.go create mode 100644 collections/rbtree/rbtree_test.go create mode 100644 collections/stack/stack.go create mode 100644 collections/stack/stack_test.go diff --git a/collections/deque/deque.go b/collections/deque/deque.go new file mode 100644 index 0000000..f1799cb --- /dev/null +++ b/collections/deque/deque.go @@ -0,0 +1,15 @@ +package deque + +import "github.com/charlienet/go-mixed/locker" + +type Deque[T any] struct { + locker locker.RWLocker +} + +func New[T any]() *Deque[T] { + return &Deque[T]{ + locker: locker.EmptyLocker, + } +} + + diff --git a/collections/deque/deque_test.go b/collections/deque/deque_test.go new file mode 100644 index 0000000..689319f --- /dev/null +++ b/collections/deque/deque_test.go @@ -0,0 +1 @@ +package deque_test diff --git a/collections/queue/queue.go b/collections/queue/queue.go new file mode 100644 index 0000000..6fb9227 --- /dev/null +++ b/collections/queue/queue.go @@ -0,0 +1,35 @@ +package queue + +import ( + "github.com/charlienet/go-mixed/collections/list" +) + +type Queue[T any] struct { + list list.LinkedList[T] +} + +func NewQueue[T any]() *Queue[T] { + return &Queue[T]{} +} + +func (q *Queue[T]) Synchronize() *Queue[T] { + q.list.Synchronize() + + return q +} + +func (q *Queue[T]) Push(v T) { + +} + +func (q *Queue[T]) Pop(v T) { + +} + +func (q *Queue[T]) Size() int { + return q.list.Size() +} + +func (q *Queue[T]) IsEmpty() bool { + return false +} diff --git a/collections/queue/queue_test.go b/collections/queue/queue_test.go new file mode 100644 index 0000000..b5079ed --- /dev/null +++ b/collections/queue/queue_test.go @@ -0,0 +1 @@ +package queue_test diff --git a/collections/rbtree/rbtree.go b/collections/rbtree/rbtree.go new file mode 100644 index 0000000..b06fe3a --- /dev/null +++ b/collections/rbtree/rbtree.go @@ -0,0 +1 @@ +package rbtree diff --git a/collections/rbtree/rbtree_test.go b/collections/rbtree/rbtree_test.go new file mode 100644 index 0000000..b06fe3a --- /dev/null +++ b/collections/rbtree/rbtree_test.go @@ -0,0 +1 @@ +package rbtree diff --git a/collections/stack/stack.go b/collections/stack/stack.go new file mode 100644 index 0000000..a5f2393 --- /dev/null +++ b/collections/stack/stack.go @@ -0,0 +1,81 @@ +package stack + +import "sync" + +var _ Stack[string] = &ArrayStack[string]{} + +type Stack[T any] interface { + Push(T) + Pop() T +} + +type ArrayStack[T any] struct { + array []T // 底层切片 + size int // 栈的元素数量 + lock sync.Mutex // 为了并发安全使用的锁 +} + +// 初始化堆栈 +func NewArrayStack[T any]() *ArrayStack[T] { + return &ArrayStack[T]{} +} + +// 入栈 +func (s *ArrayStack[T]) Push(v T) { + s.lock.Lock() + defer s.lock.Unlock() + + // 放入切片中,后进的元素放在数组最后面 + s.array = append(s.array, v) + + // 栈中元素数量+1 + s.size = s.size + 1 +} + +func (s *ArrayStack[T]) Pop() T { + s.lock.Lock() + defer s.lock.Unlock() + + if s.size == 0 { + panic("empty") + } + + // 栈顶元素 + v := s.array[s.size-1] + + // 切片收缩,但可能占用空间越来越大 + //stack.array = stack.array[0 : stack.size-1] + + // 创建新的数组,空间占用不会越来越大,但可能移动元素次数过多 + newArray := make([]T, s.size-1, s.size-1) + for i := 0; i < s.size-1; i++ { + newArray[i] = s.array[i] + } + s.array = newArray + + // 栈中元素数量-1 + s.size = s.size - 1 + return v +} + +// 获取栈顶元素 +func (s *ArrayStack[T]) Peek() T { + // 栈中元素已空 + if s.size == 0 { + panic("empty") + } + + // 栈顶元素值 + v := s.array[s.size-1] + return v +} + +// 栈大小 +func (s *ArrayStack[T]) Size() int { + return s.size +} + +// 栈是否为空 +func (s *ArrayStack[T]) IsEmpty() bool { + return s.size == 0 +} diff --git a/collections/stack/stack_test.go b/collections/stack/stack_test.go new file mode 100644 index 0000000..3246d88 --- /dev/null +++ b/collections/stack/stack_test.go @@ -0,0 +1,24 @@ +package stack_test + +import ( + "testing" + + "github.com/charlienet/go-mixed/collections/stack" +) + +func TestStack(t *testing.T) { + arrayStack := stack.NewArrayStack[string]() + arrayStack.Push("cat") + arrayStack.Push("dog") + arrayStack.Push("hen") + + t.Log("size:", arrayStack.Size()) + t.Log("pop:", arrayStack.Pop()) + t.Log("pop:", arrayStack.Pop()) + t.Log("size:", arrayStack.Size()) + arrayStack.Push("drag") + t.Log("pop:", arrayStack.Pop()) + arrayStack.Push("test") + s := arrayStack.Pop() + t.Log(s) +}