README.pt-BR.md
Este repositório contém exemplos baseados em JavaScript de muitos algoritmos e estruturas de dados populares.
Cada algoritmo e estrutura de dados possui seu próprio README com explicações relacionadas e links para leitura adicional (incluindo vídeos para YouTube)
Leia isto em outros idiomas: English 简体中文, 繁體中文, 한국어, 日本語, Polski, Français, Español, Русский, Türk, Italiana, Bahasa Indonesia, Українська, Arabic, Tiếng Việt, Deutsch, Uzbek עברית
Uma estrutura de dados é uma maneira particular de organizar e armazenar dados em um computador para que ele possa ser acessado e modificado de forma eficiente. Mais precisamente, uma estrutura de dados é uma coleção de valores de dados, as relações entre eles e as funções ou operações que podem ser aplicadas aos dados.
B - Iniciante, A - Avançado
B Lista Encadeada (Linked List)B Lista Duplamente Ligada (Doubly Linked List)B Fila (Queue)B Pilha (Stack)B Tabela de Hash (Hash Table)B Heap - versões de heap máximo e mínimoB Fila de Prioridade (Priority Queue)A Árvore de Prefixos (Trie)A Árvore (Tree)
A Árvore de Pesquisa Binária (Binary Search Tree)A Árvore AVL (AVL Tree)A Árvore Rubro-Negra (Red-Black Tree)A Árvore de Segmento (Segment Tree) - com exemplos de consultas min / max / sum rangeA Árvore Fenwick (Fenwick Tree) (Árvore indexada binária)A Grafo (Graph) (ambos dirigidos e não direcionados)A Conjunto Disjunto (Disjoint Set)A Filtro Bloom (Bloom Filter)Um algoritmo é uma especificação inequívoca de como resolver uma classe de problemas. Isto é um conjunto de regras que define precisamente uma sequência de operações.
B - Iniciante, A - Avançado
B Manipulação Bit - set/get/update/clear bits, multiplicação / divisão por dois, tornar negativo etc.B FatorialB Número de FibonacciB Teste de Primalidade (método de divisão experimental)B Algoritmo Euclidiano - Calcular o Máximo Divisor Comum (MDC)B Mínimo Múltiplo Comum Calcular o Mínimo Múltiplo Comum (MMC)B Peneira de Eratóstenes - Encontrar todos os números primos até um determinado limiteB Potência de Dois - Verifique se o número é a potência de dois (algoritmos ingênuos e bit a bit)B Triângulo de PascalB Número Complexo - Números complexos e operações básicas com elesA Partição InteiraA Algoritmo Liu Hui π - Cálculos aproximados de π baseados em N-gonsB Produto Cartesiano - Produto de vários conjuntosB Permutações de Fisher–Yates - Permutação aleatória de uma sequência finitaA Potência e Conjunto - Todos os subconjuntos de um conjuntoA Permutações (com e sem repetições)A Combinações (com e sem repetições)A Mais Longa Subsequência Comum (LCS)A Maior Subsequência CrescenteA Supersequência Comum Mais Curta (SCS)A Problema da Mochila - "0/1" e "Não consolidado"A Subarray Máximo - "Força bruta" e "Programação Dinâmica", versões de KadaneA Soma de Combinação - Encontre todas as combinações que formam uma soma específicaB Distância de Hamming - Número de posições em que os símbolos são diferentesB Palíndromos - Verifique se a cadeia de caracteres (string) é a mesma ao contrárioA Distância Levenshtein - Distância mínima de edição entre duas sequênciasA Algoritmo Knuth–Morris–Pratt (Algoritmo KMP) - Pesquisa de substring (correspondência de padrão)A Z Algorithm - Pesquisa de substring (correspondência de padrão)A Algoritmo de Rabin Karp - Pesquisa de substringA Substring Comum Mais LongaA Expressões Regulares CorrespondentesB Busca Linear (Linear Search)B Busca por Saltos (Jump Search) - Pesquisa em matriz ordenadaB Busca Binária (Binary Search) - Pesquisa em matriz ordenadaB Busca por Interpolação (Interpolation Search) - Pesquisa em matriz classificada uniformemente distribuídaB Bubble SortB Selection SortB Insertion SortB Heap SortB Merge SortB Quicksort - Implementações local e não localB ShellsortB Counting SortB Radix SortB Busca em Profundidade (Depth-First Search) (DFS)B Busca em Largura (Breadth-First Search) (BFS)B Algoritmo de Kruskal - Encontrando Árvore Mínima de Abrangência (MST) para grafo conexo com pesosA Algoritmo de Dijkstra - Encontrar caminhos mais curtos para todos os vértices do grafo a partir de um único vérticeA Algoritmo de Bellman-Ford - Encontrar caminhos mais curtos para todos os vértices do grafo a partir de um único vérticeA Algoritmo de Floyd-Warshall - Encontrar caminhos mais curtos entre todos os pares de vérticesA Detectar Ciclo - Para grafos direcionados e não direcionados (versões baseadas em DFS e Conjunto Disjuntivo)A Algoritmo de Prim - Encontrando Árvore Mínima de Abrangência (MST) para grafo não direcionado ponderadoA Ordenação Topológica - Métodos DFSA Pontos de Articulação - O algoritmo de Tarjan (baseado em DFS)A Pontes - Algoritmo baseado em DFSA Caminho e Circuito Euleriano - Algoritmo de Fleury - Visite todas as bordas exatamente uma vezA Ciclo Hamiltoniano - Visite todas as bordas exatamente uma vezA Componentes Fortemente Conectados - Algoritmo de KosarajuA Problema do Caixeiro Viajante - Rota mais curta possível que visita cada cidade e retorna à cidade de origemB Hash Polinomial - Função de hash de rolagem baseada em polinômioB Torre de HanoiB Rotação de Matriz Quadrada - Algoritmo no localB Jogo do Salto - Backtracking, programação dinâmica (top-down + bottom-up) e exemplos gananciososB Caminhos Únicos - Backtracking, programação dinâmica e exemplos baseados no triângulo de PascalB Terraços de Chuva - Problema de retenção da água da chuva (programação dinâmica e versões de força bruta)A Problema das N-RainhasA Passeio do CavaleiroUm paradigma algorítmico é um método ou abordagem genérica subjacente ao design de uma classe de algoritmos. É uma abstração maior do que a noção de um algoritmo, assim como algoritmo é uma abstração maior que um programa de computador.
B Busca Linear (Linear Search)B Terraços de Chuva - Problema de retenção de água da chuva (programação dinâmica e versões de força bruta)A Subarray MáximoA Problema do Caixeiro Viajante - Rota mais curta possível que visita cada cidade e retorna à cidade de origemB Jogo do SaltoA Problema da MochilaA Algoritmo de Dijkstra - Encontrar caminhos mais curtos para todos os vértices do grafo a partir de um único vérticeA Algoritmo de Prim - Encontrando Árvore Mínima de Abrangência (MST) para grafo não direcionado ponderadoA Algoritmo de Kruskal - Encontrando Árvore Mínima de Abrangência (MST) para grafo conexo com pesosB Busca Binária (Binary Search)B Torre de HanoiB Triângulo de PascalB Algoritmo Euclidiano - Calcular o Máximo Divisor Comum (MDC)B Merge SortB QuicksortB Busca em Profundidade (Depth-First Search) (DFS)B Busca em Largura (Breadth-First Search) (BFS)B Jogo do SaltoA Permutações (com e sem repetições)A Combinações (com e sem repetições)B Número de FibonacciB Jogo do SaltoB Caminhos ÚnicosB Terraços de Chuva - Trapping problema da água da chuvaA Distância Levenshtein - Distância mínima de edição entre duas sequênciasA Mais Longa Subsequência Comum (LCS)A Substring Comum Mais LongaA Maior Subsequência CrescenteA Supersequência Comum Mais CurtaA Problema da MochilaA Partição InteiraA Subarray MáximoA Algoritmo de Bellman-Ford - Encontrar caminhos mais curtos para todos os vértices do grafo a partir de um único vérticeA Algoritmo de Floyd-Warshall - Encontrar caminhos mais curtos entre todos os pares de vérticesA Expressões Regulares CorrespondentesB Jogo do SaltoB Caminhos ÚnicosA Ciclo Hamiltoniano - Visite todos os vértices exatamente uma vezA Problema das N-RainhasA Passeio do CavaleiroA Soma de Combinação - Encontre todas as combinações que formam uma soma específicaInstalar todas as dependências
npm install
Executar o ESLint
Você pode querer executá-lo para verificar a qualidade do código.
npm run lint
Execute todos os testes
npm test
Executar testes por nome
npm test -- 'LinkedList'
Solução de problemas
Caso o linting ou o teste estejam falhando, tente excluir a pasta node_modules e reinstalar os pacotes npm:
rm -rf ./node_modules
npm i
Verifique também se você está usando uma versão correta do Node (>=14.16.0). Se você estiver usando nvm para gerenciamento de versão do Node, você pode executar nvm use a partir da pasta raiz do projeto e a versão correta será escolhida.
Playground
Você pode brincar com estruturas de dados e algoritmos no arquivo ./src/playground/playground.js e escrever
testes para isso em ./src/playground/__test__/playground.test.js.
Em seguida, basta executar o seguinte comando para testar se o código do seu playground funciona conforme o esperado:
npm test -- 'playground'
A notação Big O é usada para classificar algoritmos de acordo com a forma como seu tempo de execução ou requisitos de espaço crescem à medida que o tamanho da entrada aumenta. No gráfico abaixo você pode encontrar as ordens mais comuns de crescimento de algoritmos especificados na notação Big O.
Fonte: Notação Big-O Dicas.
Abaixo está a lista de algumas das notações Big O mais usadas e suas comparações de desempenho em relação aos diferentes tamanhos dos dados de entrada.
| Notação Big-O | Cálculos para 10 elementos | Cálculos para 100 elementos | Cálculos para 1000 elementos |
|---|---|---|---|
| O(1) | 1 | 1 | 1 |
| O(log N) | 3 | 6 | 9 |
| O(N) | 10 | 100 | 1000 |
| O(N log N) | 30 | 600 | 9000 |
| O(N^2) | 100 | 10000 | 1000000 |
| O(2^N) | 1024 | 1.26e+29 | 1.07e+301 |
| O(N!) | 3628800 | 9.3e+157 | 4.02e+2567 |
| Estrutura de dados | Acesso | Busca | Inserção | Eliminação | Comentários |
|---|---|---|---|---|---|
| Array | 1 | n | n | n | |
| Stack | n | n | 1 | 1 | |
| Queue | n | n | 1 | 1 | |
| Linked List | n | n | 1 | 1 | |
| Hash Table | - | n | n | n | Em caso de uma função hash perfeita, os custos seriam O(1) |
| Binary Search Tree | n | n | n | n | No caso de custos de árvore equilibrados seria O(log(n)) |
| B-Tree | log(n) | log(n) | log(n) | log(n) | |
| Red-Black Tree | log(n) | log(n) | log(n) | log(n) | |
| AVL Tree | log(n) | log(n) | log(n) | log(n) | |
| Bloom Filter | - | 1 | 1 | - | Falsos positivos são possíveis durante a pesquisa |
| Nome | Melhor | Média | Pior | Mémoria | Estável | Comentários |
|---|---|---|---|---|---|---|
| Bubble sort | n | n<sup>2</sup> | n<sup>2</sup> | 1 | Sim | |
| Insertion sort | n | n<sup>2</sup> | n<sup>2</sup> | 1 | Sim | |
| Selection sort | n<sup>2</sup> | n<sup>2</sup> | n<sup>2</sup> | 1 | Não | |
| Heap sort | n log(n) | n log(n) | n log(n) | 1 | Não | |
| Merge sort | n log(n) | n log(n) | n log(n) | n | Sim | |
| Quick sort | n log(n) | n log(n) | n<sup>2</sup> | log(n) | Não | O Quicksort geralmente é feito no local com espaço de pilha O(log(n)) |
| Shell sort | n log(n) | depende da sequência de lacunas | n (log(n))<sup>2</sup> | 1 | Não | |
| Counting sort | n + r | n + r | n + r | n + r | Sim | r - maior número na matriz |
| Radix sort | n * k | n * k | n * k | n + k | Sim | k - comprimento da chave mais longa |
ℹ️ Outros projetos e artigos sobre JavaScript e algoritmos em trekhleb.dev