Go - map, list, queue, stack

map

Go에서 기본으로 제공하는 mapHash Map 구조를 가진다. 

// map[키]값

dict := map[int]string{
    1: "one",
    2: "two",
}

dict[3] = "three"

{중괄호} 안에서 초기화하거나 를 이용해 값을 삽입할 수 있다. 

dict := map[int]string{
    1: "one",
    2: "two",
}

val, exist := dict[5]
if !exist {
    fmt.Println("dict[5] doesn't exist")
} else {
    fmt.Println(val)
}  // dict[5] doesn't exist

키로 값을 가져올 때, 값과 존재 여부를 반환한다. 

for key, value := range dict {
    fmt.Printf("%d: %s\n", key, value)
}

range를 통해 map을 (k, v) 형태로 순회할 수 있다. 이때 hash map은 순서를 보장하지 않는다는 점을 주의해야 한다. 


container

go 표준 패키지 중 하나로 container를 제공한다. 

API 문서: https://pkg.go.dev/container@go1.19.3

  • list: 양방향 연결 리스트
  • ring: 환형 연결 리스트
  • heap: 힙

 

List:

package main

import (
    "container/list"
    "fmt"
)

func main() {
    l := list.New()

    eLast := l.PushBack("z")
    eHead := l.PushFront("a")

    eTwo := l.InsertAfter(2, eHead)
    l.Remove(eTwo)

    l.InsertAfter(1, eHead)
    l.InsertBefore(9, eLast)

    fmt.Printf("Len: %d\n", l.Len())
	
    for e := l.Front(); e != nil; e = e.Next() {
        fmt.Print(e.Value)
    }
}

/*
 * Len: 4
 * a19z
 */

예시로 든 list{앞 요소, 뒷 요소, 값}을 가진 객체이다. 따라서 메모리에 독립적으로 저장된 객체들을 연결시킬 수 있다. list를 활용하면 Queue, Stack과 같은 자료 구조로 확장할 수 있다. 

 

Queue:

type Queue struct {
    List *list.List
}

func NewQueue() *Queue {
    queue := Queue{list.New()}
    return &queue
}

func (q *Queue) Push(n int) {
    q.List.PushBack(n)
}

func (q *Queue) Pop() interface{} {
    val := q.List.Front()
    if val != nil {
        return q.List.Remove(val)
    }
    return nil
}

func main() {
    queue := NewQueue()
    for i := 1; i < 10; i++ {
        queue.Push(i)
    }

    for {
        val := queue.Pop()
        if val == nil {
            return
        }
        fmt.Printf("%d-", val)
    }
}  // 1-2-3-4-5-6-7-8-9-

 

Stack:

type Stack struct {
    List *list.List
}

func NewStack() *Stack {
    stack := Stack{list.New()}
    return &stack
}

func (q *Stack) Push(n int) {
    q.List.PushBack(n)
}

func (q *Stack) Pop() interface{} {
    val := q.List.Back()
    if val != nil {
        return q.List.Remove(val)
    }
    return nil
}

func main() {
    stack := NewStack()
    for i := 1; i < 10; i++ {
        stack.Push(i)
	}

    for {
        val := stack.Pop()
        if val == nil {
            return
        }
        fmt.Printf("%d-", val)
    }
}  // 9-8-7-6-5-4-3-2-1-