Introdução a algoritmos e estruturas de dados em Go
Go (Golang) é uma linguagem de programação compilada moderna, desenvolvida no Google. Ela combina o desempenho do C++ com a simplicidade do Python, tornando-a uma escolha ideal para aprender algoritmos e estruturas de dados. Neste artigo, abordaremos conceitos fundamentais que ajudarão você a começar a escrever código eficiente em Go.
Compreender estruturas de dados e algoritmos é uma habilidade essencial para qualquer desenvolvedor. Eles permitem organizar dados de forma eficiente e resolver problemas da maneira ideal. O Go oferece tipos embutidos poderosos, como slices e map, mas conhecer as estruturas básicas ajudará você a criar soluções mais complexas.
Estruturas de dados principais em Go
Arrays e Slices
Em Go, arrays têm comprimento fixo, enquanto slices são dinâmicos. Slices são uma ferramenta mais flexível e são usados com mais frequência.
package main
import "fmt"
func main() { // Array de comprimento fixo var arr [5]int = [5]int{1, 2, 3, 4, 5} fmt.Println("Array:", arr)
// Slice — array dinâmico slice := []int{10, 20, 30, 40, 50} fmt.Println("Slice:", slice)
// Adicionando elemento ao slice slice = append(slice, 60) fmt.Println("Slice após append:", slice)
// Slice de parte do array subSlice := arr[1:4] fmt.Println("Sub-slice:", subSlice)}Slices em Go são uma referência a um array subjacente. Eles contêm um ponteiro para o primeiro elemento, comprimento e capacidade. Isso os torna muito eficientes para trabalhar com sequências de dados.
Pilha (Stack) em Go
Pilha é uma estrutura de dados que opera pelo princípio LIFO (Last In, First Out). Em Go, uma pilha pode ser facilmente implementada usando um slice.
package main
import ( "fmt" "errors")
type Stack []int
func (s *Stack) Push(v int) { *s = append(*s, v)}
func (s *Stack) Pop() (int, error) { if len(*s) == 0 { return 0, errors.New("pilha vazia") } index := len(*s) - 1 element := (*s)[index] *s = (*s)[:index] return element, nil}
func main() { var stack Stack stack.Push(1) stack.Push(2) stack.Push(3) for len(stack) > 0 { val, err := stack.Pop() if err == nil { fmt.Println("Extraído:", val) } }}Pilhas são usadas em algoritmos de travessia de árvores, verificação de parênteses, desfazer ações (undo) e análise de expressões.
Fila (Queue) em Go
Fila opera pelo princípio FIFO (First In, First Out). Em Go, ela pode ser implementada usando um slice ou uma lista duplamente encadeada.
package main
import "fmt"
type Queue []int
func (q *Queue) Enqueue(v int) { *q = append(*q, v)}
func (q *Queue) Dequeue() (int, bool) { if len(*q) == 0 { return 0, false } element := (*q)[0] *q = (*q)[1:] return element, true}
func main() { queue := Queue{} queue.Enqueue(10) queue.Enqueue(20) queue.Enqueue(30) for len(queue) > 0 { val, ok := queue.Dequeue() if ok { fmt.Println("Extraído:", val) } }}Filas são aplicadas em sistemas de gerenciamento de tarefas, bufferização de dados e algoritmos de busca em largura (BFS).
Algoritmos básicos de ordenação e busca
Ordenação Bolha (Bubble Sort)
Um algoritmo de ordenação simples que percorre o array várias vezes, comparando elementos adjacentes e trocando-os se estiverem na ordem errada.
package main
import "fmt"
func bubbleSort(arr []int) { n := len(arr) for i := 0; i < n-1; i++ { for j := 0; j < n-i-1; j++ { if arr[j] > arr[j+1] { arr[j], arr[j+1] = arr[j+1], arr[j] } } }}
func main() { data