Boas-vindas a este curso de algoritmos.
Meu nome é Eric.
Audiodescrição: Eric é um homem branco, careca, que usa óculos. Ele veste uma camiseta preta e está em um estúdio amplo.
Estamos aqui para convidá-los a participar deste curso de algoritmos, que é extremamente interessante quando pensamos em algoritmos de forma mais aplicada.
Nós já utilizamos algoritmos extensivamente em nosso código, mas, por vezes, não paramos para refletir sobre eles, não conhecemos internamente as decisões de design de algoritmos que foram tomadas para cada uma das estruturas que usamos. Estruturas como fila, pilha, lista ligada, conjuntos, mapas e aquele dicionário que normalmente utilizamos na linguagem. Como essas estruturas são implementadas? Como as pessoas desenvolveram essas ideias?
A proposta deste vídeo, desta série de vídeos, deste conteúdo tão interessante, é que possamos, juntos, explorar esse caminho. Esperamos que apreciem e contamos com a presença de todos para iniciarmos essa jornada, que acreditamos será fantástica.
Olá, pessoal. Vamos começar discutindo a primeira estrutura de dados: a fila. Entre as estruturas de dados, a fila é geralmente a primeira que aprendemos, pois é baseada em um conceito simples e presente no nosso dia a dia.
Imaginemos uma manhã típica em que estamos chegando ao trabalho. Antes de chegar, passamos na padaria para pegar um café ou algo para comer. No entanto, há uma quantidade de pessoas à nossa frente, que serão atendidas antes de nós, pois chegaram primeiro. A ideia é que, pelo fato de essas pessoas terem chegado antes, elas têm prioridade no atendimento. Esse é o conceito de fila, que é comum em diversas situações do nosso cotidiano.
Por exemplo, ao comprar ingressos online para grandes festivais, há uma alta demanda, e os pedidos são atendidos em ordem de chegada. Existe a fila virtual, onde as pessoas que conseguem entrar antes têm acesso aos ingressos primeiro. Esse conceito também se aplica ao atendimento de requisições em software. À medida que as requisições chegam, elas são atendidas conforme a disponibilidade de recursos computacionais. Se houver mais requisições do que recursos, elas entram em uma fila, seguindo o padrão de que quem chega primeiro é atendido primeiro.
Por que precisamos pensar em filas ao desenvolver algoritmos? O primeiro desafio é garantir um atendimento organizado. A ideia de um atendimento organizado é crucial, pois, sem ele, não conseguimos assegurar uma regra de atendimento por ordem de chegada. Por exemplo, ao registrar transações bancárias, é necessário que elas sejam processadas na ordem correta. Se fizermos uma transferência antes de um depósito, sem o valor disponível na conta, a transferência não será possível. No entanto, se processarmos o depósito primeiro e depois a transferência, garantimos que o processamento ocorra conforme esperado.
Além disso, enfrentamos a questão do sobrecarregamento. Se há poucos recursos e muitas pessoas para atender, é essencial ter uma estrutura de fila para organizar o atendimento de forma eficiente.
Imagine que vamos entrar em um prédio onde ocorrerá um evento. Nesse prédio, há 30 pessoas para chegar e apenas 3 pessoas para atender. Temos uma restrição de recursos para processamento, com uma quantidade maior de chamadas, e essas chamadas precisam ser atendidas na ordem em que chegam. Isso é importante para que não haja uma estrutura que permita que quem chegou antes receba um atendimento diferente ou que alguém no meio da fila seja escolhido para ser atendido fora de ordem.
Quando pensamos em algoritmos, é fundamental lembrar que eles são processos. O ponto interessante ao considerar uma fila é justamente essa ideia de processo. Ao criar ou entender um algoritmo, devemos sempre pensar no processo subjacente e no problema que ele resolve. Aqui, estamos usando um exemplo cotidiano para tratar de algo técnico. A ideia da fila é essa: tiramos a ideia da fila do mundo real e a aplicamos para entender tecnicamente como resolver um problema.
O ponto central ao falarmos de fila é a previsibilidade. Sabemos que o que chegou primeiro será atendido primeiro. Essa é a regra da fila que conhecemos normalmente. Não estamos discutindo como furar a fila ou como estabelecer prioridades; estamos tratando de uma fila comum. Para entender bem o conceito, vamos implementar usando as ferramentas do Node.
Um conceito importante ao trabalhar com filas é o FIFO, que vem do inglês "First In First Out". Quando trabalhamos com filas, frequentemente ouvimos falar de filas FIFO ou LIFO. Quando falarmos sobre pilhas, abordaremos o que chamam de fila LIFO. Mas aqui estamos lidando com uma fila FIFO, ou seja, "Primeira Entrada, Primeira Saída". Em tecnologia, ouvimos muito sobre filas de primeira entrada e primeira saída, ou filas FIFO. Os conceitos são frequentemente os mesmos quando falamos de filas de atendimento.
É importante observar que a ideia da fila é uma regra de atendimento simples, não complexa. Portanto, a implementação também deve ser simples. Veremos que, à medida que os algoritmos são apresentados, eles são construídos com base na ideia de outros. Para avançarmos, pegaremos um conceito inicial, como o de fila, para fazer outras implementações. Assim, é crucial entender bem como a fila funciona, pois ela é a base. Vamos explorar como a fila funciona, ver suas implementações e sempre tentar relacionar isso à resolução de problemas.
Até a próxima!
Já discutimos um pouco sobre a teoria das filas, então agora vamos partir para a implementação. Vamos abrir o Visual Studio Code. Já criamos uma pasta dentro da nossa estrutura de projeto chamada "aula1" e, dentro dela, vamos criar um arquivo chamado fila.js, que será o arquivo em que trabalharemos agora.
Para todas as estruturas que vamos criar, utilizaremos classes. Isso facilita o encapsulamento de todas as ideias em uma única estrutura. Vamos começar criando uma classe chamada Fila.
class Fila {
}
Inicialmente, vamos definir o constructor, que não receberá nenhum parâmetro. No constructor, definiremos uma variável de array, um campo de array. Utilizaremos o array do JavaScript como base para todas as estruturas que desenvolveremos, pois é uma estrutura básica que aprendemos logo no início e que nos ajudará a entender as técnicas.
class Fila {
constructor(){
this.elementos = [];
}
}
Vamos começar criando essa estrutura com this.elementos = [], definindo assim uma lista vazia. Com isso, já temos o básico da fila, algo que consegue receber elementos. O primeiro método que implementaremos será para adicionar elementos à fila, sempre no final. Se adicionarmos três itens, o terceiro item sempre será o último. Essa será a ideia ao longo de toda a implementação da fila.
Vamos criar um método chamado enfileirar, que receberá um parâmetro elemento. A ideia é que o elemento seja adicionado na posição correspondente ao tamanho atual do array, já que o array começa a contar a partir de 0. Portanto, se o array tem dois itens, o novo elemento será colocado na posição 2.
enfileirar(elemento){
this.elementos[this.elementos.length] = elemento;
}
Agora, fora da classe, vamos realizar um teste para verificar como utilizar essa fila. Vamos criar uma constante minhaFila e instanciar a fila.
const minhaFila = new Fila();
Em seguida, utilizaremos minhaFila.enfileirar para adicionar um número.
minhaFila.enfileirar(1);
Para visualizar o array interno que estamos utilizando, faremos um console.log(minhaFila.elementos). Isso nos permitirá entender como a estrutura está sendo construída.
console.log(minhaFila.elementos);
Ao rodar o código, veremos que o array contém um único elemento, que é o número 1. Vamos tentar enfileirar mais elementos, como 2 e 3.
minhaFila.enfileirar(2);
minhaFila.enfileirar(3);
Quando olharmos o resultado, veremos os números 1, 2 e 3, indicando que a fila está funcionando corretamente.
Agora precisamos começar a consumir esses itens. Sempre consumiremos o primeiro item da fila. Para isso, criaremos um método retirar dentro da classe Fila.
retirar(){
if (this.elementos.length == 0){
return null;
}
const elementoARetornar = this.elementos[0];
this.elementos = this.elementos.slice(1, this.elementos.length);
return elementoARetornar;
}
O método retirar não precisará de parâmetros, pois apenas solicitará a remoção de um item. Se a fila estiver vazia, retornaremos null. Caso contrário, armazenaremos o primeiro elemento em uma constante elementoARetornar e utilizaremos o método slice para removê-lo do array.
Com isso, implementamos a funcionalidade básica de uma fila, permitindo adicionar e remover elementos conforme necessário.
O que o slice faz?
Precisamos passar o início e o final. O início será 1 e o final será o tamanho da nossa fila, this.elementos.length. O que fizemos aqui? Vamos dar uma olhada. No método retirar, na linha 10, estamos testando se o nosso array de elementos está vazio. Se estiver vazio, retornamos null. Caso contrário, pegamos um elemento para retornar. Na linha 14, definimos const elementoRetornar = this.elementos[0]. Na linha 15, ajustamos a nossa nova lista, removendo o primeiro item. No final, retornamos o elemento a ser retornado. Essa é a implementação do método retirar.
Vamos fazer algo interessante: retirar o primeiro item. Saímos da classe que estávamos desenvolvendo e, com as entradas feitas, na linha 24, criamos const itemRetirado = minhaFila.retirar(). O que vamos salvar aqui? Ao enfileirar três elementos, retiramos um.
const itemRetirado = minhaFila.retirar();
console.log("item retirado: ", itemRetirado);
No terminal, a saída da execução do script mostra a listagem 1, 2 e 3. Vamos verificar se o 1, que é o primeiro da lista, foi retirado. Usamos console.log(itemRetirado) para mostrar o item retirado na tela de saída.
Ao clicar em "run code", verificamos que o item retirado foi 1, e os elementos restantes são 2 e 3. Na execução, enfileiramos três elementos nas linhas 22, 23 e 24, e na linha 25 retiramos o 1. O item retirado apareceu corretamente. Podemos fazer outro teste: enfileirar mais um número.
minhaFila.enfileirar(4);
Ao executar novamente, vemos que o 4 foi adicionado, resultando em um array com 2, 3 e 4.
Se fizermos novamente const itemRetiradoNovo = minhaFila.retirar(), imprimimos o item retirado novo com console.log("Item retirado novo:", itemRetiradoNovo), e em seguida imprimimos a lista final com console.log(minhaFila.elementos).
const itemRetiradoNovo = minhaFila.retirar();
console.log("item retirado novo: ", itemRetiradoNovo);
console.log(minhaFila.elementos);
Ao executar novamente, vemos que criamos 1, 2, 3, retiramos 1, enfileiramos 4, resultando em 2, 3, 4. Retiramos mais um, o 2, e no final ficaram 3 e 4. Observamos que os primeiros a entrar foram os primeiros a sair.
Precisamos implementar dois últimos itens. Primeiro, verificar se a fila está vazia, o que é importante para decidir se continuamos a trabalhar com ela. Criamos a função estaVazia(), que retorna true se this.elementos.length for igual a zero, e false caso contrário. Retornamos esse valor.
estaVazia(){
const vazia = this.elementos.length == 0;
return vazia;
}
O último item é verificar o tamanho da fila. Criamos a função tamanho(), que retorna this.elementos.length.
tamanho(){
return this.elementos.length;
}
Nos testes de codificação, na linha 40, usamos console.log("A fila está vazia:", minhaFila.estaVazia()) e console.log("Tamanho atual da fila:", minhaFila.tamanho()).
console.log("a fila está vazia?", minhaFila.estaVazia());
console.log("tamanho atual da fila:", minhaFila.tamanho());
Ao executar novamente, verificamos que a fila não está vazia e o tamanho atual é 2, conforme mostrado na saída.
Implementamos a fila de forma padrão, utilizando o que o JavaScript permite, que é o array, e implementando as ações. Quando usamos a fila, apesar de olharmos dentro dela, não utilizamos o elemento diretamente, apenas os métodos enfileirar e retirar. Até a próxima!
O curso Node.js: dominando filas, pilhas e estruturas de dados possui 213 minutos de vídeos, em um total de 48 atividades. Gostou? Conheça nossos outros cursos de Node.JS em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Mobile, Programação, Front-end, DevOps, UX & Design, Marketing Digital, Data Science, Inovação & Gestão, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para estudantes ultra comprometidos atingirem seu objetivo mais rápido.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.