golang container package

container package

golang์—๋Š” ๋นŒํŠธ์ธ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” container package๊ฐ€ ์žˆ๋‹ค.

๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด, ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•  ์ผ์ด ๊ฝค ์ƒ๊ธด๋‹ค.

go์—์„œ๋Š” container ํŒจํ‚ค์ง€์—์„œ ๊ธฐ๋ณธ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•ด์ฃผ๋ฏ€๋กœ ๊ฝค๋‚˜ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŒจํ‚ค์ง€์—์„œ ์ œ๊ณตํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • Linked list

  • Heap

  • Ring (Circular list)

container ํŒจํ‚ค์ง€๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ„๋‹จํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž.

container/list

package main

import (
	"container/list"
	"log"
)

func main() {
	lst := list.New()
	lst.PushBack(1)
	lst.PushBack(2)
	lst.PushBack(3)

	log.Println(lst.Len())
}

์œ„์™€ ๊ฐ™์ด container/list ํŒจํ‚ค์ง€๋ฅผ importํ•˜๋ฉด, ์†์‰ฝ๊ฒŒ linked list๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ linked list๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๊ฝค๋‚˜ ์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œํ‚ฌ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

list๋ฅผ ์ˆœํšŒํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

package main

import (
	"container/list"
	"fmt"
	"log"
)

func main() {
	lst := list.New()
	lst.PushBack(1)
	lst.PushBack(2)
	lst.PushBack(3)

	log.Println(lst.Len())

	for e := lst.Front(); e != nil; e = e.Next() { // ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ˆœํšŒ
		fmt.Println(e.Value)
	}
}

container/heap

๋‹ค์Œ์€ heap ํŒจํ‚ค์ง€์ด๋‹ค. ํ•„์ž๋Š” ์ตœ๊ทผ ํšŒ์‚ฌ์—์„œ ์ฒด๊ฒฐ์—”์ง„/์˜ค๋”๋ถ์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ min heap๊ณผ max heap์„ ๊ตฌํ˜„ํ•  ์ผ์ด ์žˆ์—ˆ๋Š”๋ฐ,

container/heap ํŒจํ‚ค์ง€๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

heap ํŒจํ‚ค์ง€์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

package heap 

type Interface interface {
	Len() int
	Less(i, j int) bool
	Swap(i, j int)
	Push(x any)
	Pop() any  
}

ํ•œ ๋ฒˆ ๊ตฌํ˜„ํ•ด์„œ ์‚ฌ์šฉํ•ด๋ณด์ž. ์˜ˆ์ œ์—์„œ๋Š” min heap์„ ๊ตฌํ˜„ํ•ด๋ณธ๋‹ค.

package main

import (
	"container/heap"
	"log"
)

type IMinHeap interface {
	heap.Interface
}

type MinHeap struct {
	heap []uint
}

func (m *MinHeap) Len() int {
	return len(m.heap)
}

func (m *MinHeap) Less(i, j int) bool {
	return m.heap[i] < m.heap[j]
}

func (m *MinHeap) Swap(i, j int) {
	m.heap[i], m.heap[j] = m.heap[j], m.heap[i]
}

func (m *MinHeap) Push(x any) {
	m.heap = append(m.heap, x.(uint))
}

func (m *MinHeap) Pop() any {
	old := m.heap
	n := len(old)
	element := old[n-1]
	m.heap = old[0 : n-1]
	return element
}

func main() {
	minHeap := &MinHeap{heap: []uint{}}

	heap.Init(minHeap)

	heap.Push(minHeap, uint(10))
	heap.Push(minHeap, uint(20))
	heap.Push(minHeap, uint(50))
	heap.Push(minHeap, uint(5))

	log.Println(heap.Pop(minHeap)) // 5
	log.Println(heap.Pop(minHeap)) // 10
	log.Println(heap.Pop(minHeap)) // 20
	log.Println(heap.Pop(minHeap)) // 50
}

Less ์กฐ๊ฑด์˜ ๋ถ€ํ˜ธ๋งŒ ๋ฐ˜๋Œ€๋กœ ๋ฐ”๊ฟ”์ค˜๋„ max heap์œผ๋กœ ๋ฐ”๊พธ์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ํŽธํ•˜๋‹ค.

container/ring

๋‹ค์Œ์€ ring์ด๋‹ค. ring์€ ๋น„๊ต์  ์‚ฌ์šฉํ•  ์ผ์ด ๋งŽ์ด ์—†๋Š” ๋“ฏ ๋ณด์ด์ง€๋งŒ, ์•Œ์•„๋‘๋ฉด ๋•Œ๋•Œ๋กœ ๋„์›€์ด ๋  ์ˆ˜๋„ ์žˆ๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ๋Š” list๋ฅผ ์“ฐ๋Š” ํŽธ์ด๊ธด ํ•˜๋‹ค.

package main

import (
	"container/ring"
	"fmt"
)

func main() {
	data := []string{"Maria", "John", "Andrew", "James"}
	r := ring.New(len(data))       // ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ ๋ง ์ƒ์„ฑ
	for i := 0; i < r.Len(); i++ { // ๋ง ๋…ธ๋“œ ๊ฐœ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต
		r.Value = data[i] // ๋ง์˜ ๋…ธ๋“œ์— ๊ฐ’ ๋„ฃ๊ธฐ
		r = r.Next()      // ๋‹ค์Œ ๋…ธ๋“œ๋กœ  ์ด๋™
	}

	r.Do(func(x interface{}) { // ๋ง์˜ ๋ชจ๋“  ๋…ธ๋“œ ์ˆœํšŒ
		fmt.Println(x)
	})

	// "Maria" 
	// "John" 
	// "Andrew"
	// "James"
}

๋‘ ๊ฐœ์˜ ring์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ๋„ ๋ฌผ๋ก  ๊ฐ€๋Šฅํ•˜๋‹ค.

package main

import (
	"container/ring"
	"fmt"
)

func main() {
	data := []string{"Maria", "John", "Andrew", "James"}
	r := ring.New(len(data))       // ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ ๋ง ์ƒ์„ฑ
	for i := 0; i < r.Len(); i++ { // ๋ง ๋…ธ๋“œ ๊ฐœ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต
		r.Value = data[i] // ๋ง์˜ ๋…ธ๋“œ์— ๊ฐ’ ๋„ฃ๊ธฐ
		r = r.Next()      // ๋‹ค์Œ ๋…ธ๋“œ๋กœ  ์ด๋™
	}

	r.Do(func(x interface{}) { // ๋ง์˜ ๋ชจ๋“  ๋…ธ๋“œ ์ˆœํšŒ
		fmt.Println(x)
	})

	// "Maria" 
	// "John" 
	// "Andrew"
	// "James"

	newData := []uint{1, 2, 3, 4}

	r2 := ring.New(len(newData))
	for i := 0; i < r2.Len(); i++ { // ๋ง ๋…ธ๋“œ ๊ฐœ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต
		r2.Value = newData[i] // ๋ง์˜ ๋…ธ๋“œ์— ๊ฐ’ ๋„ฃ๊ธฐ
		r2 = r2.Next()        // ๋‹ค์Œ ๋…ธ๋“œ๋กœ  ์ด๋™
	}

	r3 := r.Link(r2)

	r3.Do(func(x interface{}) { // ๋ง์˜ ๋ชจ๋“  ๋…ธ๋“œ ์ˆœํšŒ
		fmt.Println(x)
	})
	// John
	// Andrew
	// James
	// Maria
	// 1
	// 2
	// 3
	// 4
}

Last updated