Golang의 대기열 구현
Jay Singh
2023년1월30일
스택과 같은 대기열
은 논리적 순서로 항목을 정렬하는 일반적인 데이터 구조입니다. queue
는 FIFO
(First In First Out) 메커니즘을 사용합니다. 이 메커니즘에서는 대기열에 넣은 첫 번째 항목도 대기열에서 가장 먼저 제거됩니다.
다음을 통해 Golang에서 기본 대기열을 만들 수 있습니다.
- 슬라이스
- 컨테이너/리스트 패키지
Golang에서 slice
를 사용한 대기열 구현
대기열이 FIFO
(선입 선출) 구조를 따르기 때문에 대기열에서 빼거나 대기열에 추가 작업을 다음과 같이 수행할 수 있습니다.
- 대기열에 넣으려면 내장
add
기능을 사용하십시오. - 대기열에서 빼려면 초기 조각을
슬라이스
하십시오.
예 1:
package main
import "fmt"
type StringQueue struct {
queue []string
}
func (q *StringQueue) Enqueue(s string) {
q.queue = append(q.queue, s)
}
func (q *StringQueue) Top() string {
return q.queue[0]
}
func (q *StringQueue) Dequeue() string {
temp := q.queue[0]
q.queue = q.queue[1:]
return temp
}
func (q *StringQueue) Empty() bool {
return len(q.queue) == 0
}
func main() {
fmt.Println("Queues")
queue := StringQueue{make([]string, 0)}
(&queue).Enqueue("Item 1")
(&queue).Enqueue("Item 2")
fmt.Println("Top:", (&queue).Top())
fmt.Println("Dequeued", (&queue).Dequeue())
fmt.Println("New Top:", (&queue).Top())
fmt.Println("Empty?", (&queue).Empty())
fmt.Println("Dequeued", (&queue).Dequeue())
fmt.Println("Empty now?", (&queue).Empty())
}
출력:
Queues
Top: Item 1
Dequeued Item 1
New Top: Item 2
Empty? false
Dequeued Item 2
Empty now? true
예 2:
package main
import (
"fmt"
"sync"
)
type customQueue struct {
queue []string
lock sync.RWMutex
}
func (c *customQueue) Enqueue(name string) {
c.lock.Lock()
defer c.lock.Unlock()
c.queue = append(c.queue, name)
}
func (c *customQueue) Dequeue() error {
if len(c.queue) > 0 {
c.lock.Lock()
defer c.lock.Unlock()
c.queue = c.queue[1:]
return nil
}
return fmt.Errorf("Pop Error - Queue is empty")
}
func (c *customQueue) Front() (string, error) {
if len(c.queue) > 0 {
c.lock.Lock()
defer c.lock.Unlock()
return c.queue[0], nil
}
return "", fmt.Errorf("Peep Error - Queue is empty")
}
func (c *customQueue) Size() int {
return len(c.queue)
}
func (c *customQueue) Empty() bool {
return len(c.queue) == 0
}
func main() {
customQueue := &customQueue{
queue: make([]string, 0),
}
fmt.Printf("Enqueue: 1\n")
customQueue.Enqueue("1")
fmt.Printf("Enqueue: 2\n")
customQueue.Enqueue("2")
fmt.Printf("Len: %d\n", customQueue.Size())
for customQueue.Size() > 0 {
frontVal, _ := customQueue.Front()
fmt.Printf("Front: %s\n", frontVal)
fmt.Printf("Dequeue: %s\n", frontVal)
customQueue.Dequeue()
}
fmt.Printf("Len: %d\n", customQueue.Size())
}
출력:
Enqueue: 1
Enqueue: 2
Len: 2
Front: 1
Dequeue: 1
Front: 2
Dequeue: 2
Len: 0
Golang에서 container/list
를 사용한 대기열 구현
메모리 누수를 피하기 위해 동적 데이터 구조 연결 목록
을 사용할 수 있습니다.
예 1:
package main
import (
"container/list"
"fmt"
)
func main() {
// new linked list
queue := list.New()
// Simply append to enqueue.
queue.PushBack(10)
queue.PushBack(20)
queue.PushBack(30)
// Dequeue
front := queue.Front()
fmt.Println(front.Value)
// This frees up memory and prevents memory leaks.
queue.Remove(front)
}
출력:
10
예 2:
package main
import (
"container/list"
"fmt"
)
type customQueue struct {
queue *list.List
}
func (c *customQueue) Enqueue(value string) {
c.queue.PushBack(value)
}
func (c *customQueue) Dequeue() error {
if c.queue.Len() > 0 {
ele := c.queue.Front()
c.queue.Remove(ele)
}
return fmt.Errorf("Pop Error: Queue is empty")
}
func (c *customQueue) Front() (string, error) {
if c.queue.Len() > 0 {
if val, ok := c.queue.Front().Value.(string); ok {
return val, nil
}
return "", fmt.Errorf("Peep Error: Queue Datatype is incorrect")
}
return "", fmt.Errorf("Peep Error: Queue is empty")
}
func (c *customQueue) Size() int {
return c.queue.Len()
}
func (c *customQueue) Empty() bool {
return c.queue.Len() == 0
}
func main() {
customQueue := &customQueue{
queue: list.New(),
}
fmt.Printf("Enqueue: A\n")
customQueue.Enqueue("A")
fmt.Printf("Enqueue: B\n")
customQueue.Enqueue("B")
fmt.Printf("Size: %d\n", customQueue.Size())
for customQueue.Size() > 0 {
frontVal, _ := customQueue.Front()
fmt.Printf("Front: %s\n", frontVal)
fmt.Printf("Dequeue: %s\n", frontVal)
customQueue.Dequeue()
}
fmt.Printf("Size: %d\n", customQueue.Size())
}
출력:
Enqueue: A
Enqueue: B
Size: 2
Front: A
Dequeue: A
Front: B
Dequeue: B
Size: 0