mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-26 03:16:29 +08:00
feat(deque): add implementation of deque
This commit is contained in:
parent
19469aecbf
commit
a554590fa8
3 changed files with 155 additions and 1 deletions
53
codes/go/chapter_stack_and_queue/deque_test.go
Normal file
53
codes/go/chapter_stack_and_queue/deque_test.go
Normal file
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
102
codes/go/chapter_stack_and_queue/linkedlist_deque.go
Normal file
102
codes/go/chapter_stack_and_queue/linkedlist_deque.go
Normal file
|
@ -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()
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ package chapter_stack_and_queue
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestArrayQueue(t *testing.T) {
|
func TestArrayQueue(t *testing.T) {
|
||||||
|
|
||||||
// 初始化队列,使用队列的通用接口
|
// 初始化队列,使用队列的通用接口
|
||||||
var queue Queue
|
var queue Queue
|
||||||
capacity := 10
|
capacity := 10
|
||||||
|
|
Loading…
Reference in a new issue