From a554590fa81b75ce156121aae74619d1a998d430 Mon Sep 17 00:00:00 2001 From: reanon <793584285@qq.com> Date: Tue, 29 Nov 2022 10:43:47 +0800 Subject: [PATCH] feat(deque): add implementation of deque --- .../go/chapter_stack_and_queue/deque_test.go | 53 +++++++++ .../linkedlist_deque.go | 102 ++++++++++++++++++ .../go/chapter_stack_and_queue/queue_test.go | 1 - 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 codes/go/chapter_stack_and_queue/deque_test.go create mode 100644 codes/go/chapter_stack_and_queue/linkedlist_deque.go diff --git a/codes/go/chapter_stack_and_queue/deque_test.go b/codes/go/chapter_stack_and_queue/deque_test.go new file mode 100644 index 000000000..c0eaf089e --- /dev/null +++ b/codes/go/chapter_stack_and_queue/deque_test.go @@ -0,0 +1,53 @@ +// File: deque_test.go +// Created Time: 2022-11-29 +// Author: Reanon (793584285@qq.com) + +package chapter_stack_and_queue + +import "testing" + +func TestLinkedListDeque(t *testing.T) { + // 初始化队列 + var deque Deque + deque = NewLinkedListDeque() + + // 元素入队 + deque.OfferLast(2) + deque.OfferLast(5) + deque.OfferLast(4) + deque.OfferFirst(3) + deque.OfferFirst(1) + t.Log("队列 deque = ", deque.toString()) + + // 访问队首元素 + peekFirst := deque.PeekFirst() + t.Log("队首元素 peek = ", peekFirst) + peekLast := deque.PeekLast() + t.Log("队尾元素 peek = ", peekLast) + + // 元素出队 + pollFirst := deque.PollFirst() + t.Log("队首出队元素 pollFirst = ", pollFirst, ",队首出队后 deque = ", deque.toString()) + pollLast := deque.PollLast() + t.Log("队尾出队元素 pollLast = ", pollLast, ",队尾出队后 deque = ", deque.toString()) + + // 获取队的长度 + size := deque.Size() + t.Log("队的长度 size = ", size) + + // 判断是否为空 + isEmpty := deque.IsEmpty() + t.Log("队是否为空 = ", isEmpty) +} + +// BenchmarkArrayQueue 67.92 ns/op in Mac M1 Pro +func BenchmarkLinkedListDeque(b *testing.B) { + stack := NewLinkedListDeque() + // use b.N for looping + for i := 0; i < b.N; i++ { + stack.OfferLast(777) + } + for i := 0; i < b.N; i++ { + stack.PollFirst() + } +} diff --git a/codes/go/chapter_stack_and_queue/linkedlist_deque.go b/codes/go/chapter_stack_and_queue/linkedlist_deque.go new file mode 100644 index 000000000..62a614910 --- /dev/null +++ b/codes/go/chapter_stack_and_queue/linkedlist_deque.go @@ -0,0 +1,102 @@ +// File: linkedlist_deque.go +// Created Time: 2022-11-29 +// Author: Reanon (793584285@qq.com) + +package chapter_stack_and_queue + +import ( + "container/list" + "fmt" + "strings" +) + +// LinkedListDeque 基于链表实现的双端队列, 使用内置包 list 来实现栈 +type LinkedListDeque struct { + list *list.List +} + +// NewLinkedListDeque 初始化双端队列 +func NewLinkedListDeque() *LinkedListDeque { + return &LinkedListDeque{ + list: list.New(), + } +} + +// OfferFirst 元素入队 +func (s *LinkedListDeque) OfferFirst(value any) { + s.list.PushFront(value) +} + +// OfferLast 元素入队 +func (s *LinkedListDeque) OfferLast(value any) { + s.list.PushBack(value) +} + +// PollFirst 元素出队 +func (s *LinkedListDeque) PollFirst() any { + if s.IsEmpty() { + return nil + } + e := s.list.Front() + s.list.Remove(e) + return e.Value +} + +// PollLast 元素出队 +func (s *LinkedListDeque) PollLast() any { + if s.IsEmpty() { + return nil + } + e := s.list.Back() + s.list.Remove(e) + return e.Value +} + +// PeekFirst 访问首元素 +func (s *LinkedListDeque) PeekFirst() any { + if s.IsEmpty() { + return nil + } + e := s.list.Front() + return e.Value +} + +// PeekLast 访问尾元素 +func (s *LinkedListDeque) PeekLast() any { + if s.IsEmpty() { + return nil + } + e := s.list.Back() + return e.Value +} + +// Size 获取队列的长度 +func (s *LinkedListDeque) Size() int { + return s.list.Len() +} + +// IsEmpty 判断队列是否为空 +func (s *LinkedListDeque) IsEmpty() bool { + return s.list.Len() == 0 +} + +func (s *LinkedListDeque) Print() { + fmt.Println(s.toString()) +} + +func (s *LinkedListDeque) toString() string { + var builder strings.Builder + if s.IsEmpty() { + fmt.Println("empty stack") + } + e := s.list.Front() + // 强转为 string, 会影响效率 + str := fmt.Sprintf("%v", e.Value) + for e.Next() != nil { + builder.WriteString(str + " -> ") + e = e.Next() + str = fmt.Sprintf("%v", e.Value) + } + builder.WriteString(str) + return builder.String() +} diff --git a/codes/go/chapter_stack_and_queue/queue_test.go b/codes/go/chapter_stack_and_queue/queue_test.go index 996b0bcdb..e8c74ecba 100644 --- a/codes/go/chapter_stack_and_queue/queue_test.go +++ b/codes/go/chapter_stack_and_queue/queue_test.go @@ -7,7 +7,6 @@ package chapter_stack_and_queue import "testing" func TestArrayQueue(t *testing.T) { - // 初始化队列,使用队列的通用接口 var queue Queue capacity := 10