diff --git a/collections/circlequeue.go b/collections/circlequeue.go index f3e19b2..b821c31 100644 --- a/collections/circlequeue.go +++ b/collections/circlequeue.go @@ -2,23 +2,23 @@ package collections import "fmt" -type CircleQueue struct { +type CircleQueue[T any] struct { data []any cap int front int rear int } -func NewCircleQueue(cap int) *CircleQueue { +func NewCircleQueue[T any](cap int) *CircleQueue[T] { cap++ - return &CircleQueue{ + return &CircleQueue[T]{ data: make([]any, cap), cap: cap, } } -func (q *CircleQueue) Push(data any) bool { +func (q *CircleQueue[T]) Push(data any) bool { if (q.rear+1)%q.cap == q.front { return false } @@ -27,7 +27,7 @@ func (q *CircleQueue) Push(data any) bool { q.rear = (q.rear + 1) % q.cap return true } -func (q *CircleQueue) Pop() any { +func (q *CircleQueue[T]) Pop() any { if q.rear == q.front { return nil } @@ -38,18 +38,18 @@ func (q *CircleQueue) Pop() any { return data } -func (q *CircleQueue) Size() int { +func (q *CircleQueue[T]) Size() int { return (q.rear - q.front + q.cap) % q.cap } -func (q *CircleQueue) IsFull() bool { +func (q *CircleQueue[T]) IsFull() bool { return (q.rear+1)%q.cap == q.front } -func (q *CircleQueue) IsEmpty() bool { +func (q *CircleQueue[T]) IsEmpty() bool { return q.front == q.rear } -func (q *CircleQueue) Show() string { +func (q *CircleQueue[T]) Show() string { return fmt.Sprintf("%v", q.data) } diff --git a/collections/circlequeue_test.go b/collections/circlequeue_test.go index c8218ef..d08c7ad 100644 --- a/collections/circlequeue_test.go +++ b/collections/circlequeue_test.go @@ -3,7 +3,7 @@ package collections import "testing" func TestCircleQueue(t *testing.T) { - q := NewCircleQueue(10) + q := NewCircleQueue[string](10) t.Log("Size:", q.Size()) for i := 0; i < 10; i++ { diff --git a/collections/list.go b/collections/list.go new file mode 100644 index 0000000..d8c1d7e --- /dev/null +++ b/collections/list.go @@ -0,0 +1,13 @@ +package collections + +type List[T any] interface { + Add(T) + Delete(T) + Count() int + ToSlice() []T +} + + +type Queue interface{ + +} \ No newline at end of file diff --git a/collections/queue.go b/collections/queue.go index 6e0ee07..5e1d424 100644 --- a/collections/queue.go +++ b/collections/queue.go @@ -3,40 +3,40 @@ package collections import "sync" // 数组队列,先进先出 -type ArrayQueue struct { - array []any // 底层切片 - size int // 队列的元素数量 - lock sync.Mutex // 为了并发安全使用的锁 +type ArrayQueue[T any] struct { + array []T // 底层切片 + size int // 队列的元素数量 + lock sync.Mutex // 为了并发安全使用的锁 } -func NewArrayQueue[T any]() *ArrayQueue { - return &ArrayQueue{} +func NewArrayQueue[T any]() *ArrayQueue[T] { + return &ArrayQueue[T]{} } // 入队 -func (queue *ArrayQueue) Add(v any) { - queue.lock.Lock() - defer queue.lock.Unlock() +func (q *ArrayQueue[T]) Add(v T) { + q.lock.Lock() + defer q.lock.Unlock() // 放入切片中,后进的元素放在数组最后面 - queue.array = append(queue.array, v) + q.array = append(q.array, v) // 队中元素数量+1 - queue.size = queue.size + 1 + q.size = q.size + 1 } // 出队 -func (queue *ArrayQueue) Remove() any { - queue.lock.Lock() - defer queue.lock.Unlock() +func (q *ArrayQueue[T]) Remove() any { + q.lock.Lock() + defer q.lock.Unlock() // 队中元素已空 - if queue.size == 0 { + if q.size == 0 { panic("empty") } // 队列最前面元素 - v := queue.array[0] + v := q.array[0] /* 直接原位移动,但缩容后继的空间不会被释放 for i := 1; i < queue.size; i++ { @@ -48,24 +48,24 @@ func (queue *ArrayQueue) Remove() any { */ // 创建新的数组,移动次数过多 - newArray := make([]any, queue.size-1) - for i := 1; i < queue.size; i++ { + newArray := make([]T, q.size-1) + for i := 1; i < q.size; i++ { // 从老数组的第一位开始进行数据移动 - newArray[i-1] = queue.array[i] + newArray[i-1] = q.array[i] } - queue.array = newArray + q.array = newArray // 队中元素数量-1 - queue.size = queue.size - 1 + q.size = q.size - 1 return v } // 栈大小 -func (queue *ArrayQueue) Size() int { - return queue.size +func (q *ArrayQueue[T]) Size() int { + return q.size } // 栈是否为空 -func (queue *ArrayQueue) IsEmpty() bool { - return queue.size == 0 +func (q *ArrayQueue[T]) IsEmpty() bool { + return q.size == 0 } diff --git a/collections/stack.go b/collections/stack.go index c9b6c85..6cf5807 100644 --- a/collections/stack.go +++ b/collections/stack.go @@ -2,72 +2,79 @@ package collections import "sync" -type ArrayStack struct { - array []any // 底层切片 +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 { - return &ArrayStack{} +func NewArrayStack[T any]() *ArrayStack[T] { + return &ArrayStack[T]{} } // 入栈 -func (stack *ArrayStack) Push(v any) { - stack.lock.Lock() - defer stack.lock.Unlock() +func (s *ArrayStack[T]) Push(v T) { + s.lock.Lock() + defer s.lock.Unlock() // 放入切片中,后进的元素放在数组最后面 - stack.array = append(stack.array, v) + s.array = append(s.array, v) // 栈中元素数量+1 - stack.size = stack.size + 1 + s.size = s.size + 1 } -func (stack *ArrayStack) Pop() any { - stack.lock.Lock() - defer stack.lock.Unlock() +func (s *ArrayStack[T]) Pop() T { + s.lock.Lock() + defer s.lock.Unlock() - if stack.size == 0 { + if s.size == 0 { panic("empty") } // 栈顶元素 - v := stack.array[stack.size-1] + v := s.array[s.size-1] // 切片收缩,但可能占用空间越来越大 //stack.array = stack.array[0 : stack.size-1] // 创建新的数组,空间占用不会越来越大,但可能移动元素次数过多 - newArray := make([]any, stack.size-1, stack.size-1) - for i := 0; i < stack.size-1; i++ { - newArray[i] = stack.array[i] + newArray := make([]T, s.size-1, s.size-1) + for i := 0; i < s.size-1; i++ { + newArray[i] = s.array[i] } - stack.array = newArray + s.array = newArray // 栈中元素数量-1 - stack.size = stack.size - 1 + s.size = s.size - 1 return v } // 获取栈顶元素 -func (stack *ArrayStack) Peek() any { +func (s *ArrayStack[T]) Peek() T { // 栈中元素已空 - if stack.size == 0 { + if s.size == 0 { panic("empty") } // 栈顶元素值 - v := stack.array[stack.size-1] + v := s.array[s.size-1] return v } // 栈大小 -func (stack *ArrayStack) Size() int { - return stack.size +func (s *ArrayStack[T]) Size() int { + return s.size } // 栈是否为空 -func (stack *ArrayStack) IsEmpty() bool { - return stack.size == 0 +func (s *ArrayStack[T]) IsEmpty() bool { + return s.size == 0 } diff --git a/collections/stack_test.go b/collections/stack_test.go index a396bf3..07810eb 100644 --- a/collections/stack_test.go +++ b/collections/stack_test.go @@ -7,7 +7,7 @@ import ( ) func TestStack(t *testing.T) { - arrayStack := new(collections.ArrayStack) + arrayStack := collections.NewArrayStack[string]() arrayStack.Push("cat") arrayStack.Push("dog") arrayStack.Push("hen") @@ -19,6 +19,6 @@ func TestStack(t *testing.T) { arrayStack.Push("drag") t.Log("pop:", arrayStack.Pop()) arrayStack.Push("test") - s := arrayStack.Pop().(string) + s := arrayStack.Pop() t.Log(s) }