Algoritmos que todo desenvolvedor JavaScript deve conhecer

Algoritmos que todo desenvolvedor JavaScript deve conhecer

Algoritmos são fundamentais no desenvolvimento de software. Como desenvolvedor JavaScript, compreender e aplicar algoritmos eficientes e estruturas de dados adequadas pode fazer a diferença no desempenho e na escalabilidade de seus aplicativos.

Neste artigo explicaremos alguns dos algoritmos mais utilizados que todo desenvolvedor JavaScript deve conhecer.


O que são os algoritmos?

Algoritmos são conjuntos de instruções ou etapas lógicas que resolvem um problema ou executam uma tarefa específica. No contexto da programação, os algoritmos são a base fundamental para a resolução de problemas de forma eficiente e automatizada.

Importância de usar algoritmos eficientes

Usar algoritmos eficientes é crucial para desenvolvedores de JavaScript. Um algoritmo eficiente permite que as tarefas sejam concluídas em menos tempo e com menos recursos, o que se traduz numa melhor experiência para os utilizadores finais.

Ao dominar os algoritmos, os desenvolvedores podem otimizar o desempenho de seus aplicativos, melhorar a escalabilidade e reduzir os tempos de resposta. Isso se traduz em aplicativos mais rápidos, mais eficientes e capazes de lidar com eficácia com os desafios e demandas do mundo real.

Algoritmos de pesquisa

Algoritmos de pesquisa são essenciais no desenvolvimento de aplicações para encontrar elementos específicos em um conjunto de dados. Em JavaScript, existem vários algoritmos de pesquisa comuns, dois dos quais são o Algoritmo de Pesquisa Linear e o Algoritmo de Pesquisa Binária.

Algoritmo de Pesquisa Linear

O Algoritmo de Pesquisa Linear é o método mais simples e direto para pesquisar um elemento em uma lista ou array. Comece a partir do primeiro elemento e percorra cada um deles sequencialmente até encontrar a correspondência desejada. Na pior das hipóteses, se o elemento estiver no final da lista, todos os elementos serão percorridos.

function busquedaLineal(arr, elemento) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === elemento) {
      return i; // Retorna el índice del elemento encontrado
    }
  }
  return -1; // Retorna -1 si el elemento no se encuentra en el arreglo
}

const arreglo = [10, 5, 3, 8, 2, 6];
const elementoBuscado = 8;
const indice = busquedaLineal(arreglo, elementoBuscado);
console.log(`El elemento ${elementoBuscado} se encuentra en el índice ${indice}.`);


// Output:

// El elemento 8 se encuentra en el índice 3.



Algoritmo de Pesquisa Binária

O Algoritmo de Pesquisa Binária é uma técnica mais eficiente para pesquisar elementos em uma lista ordenada. Ele funciona reduzindo repetidamente pela metade o intervalo de pesquisa até que uma correspondência seja encontrada.

Essa abordagem aproveita a propriedade de os dados serem ordenados, permitindo que metade dos elementos sejam descartados a cada etapa.

function busquedaBinaria(arr, elemento) {
  let inicio = 0;
  let fin = arr.length - 1;

  while (inicio <= fin) {
    let medio = Math.floor((inicio + fin) / 2);
    if (arr[medio] === elemento) {
      return medio; // Retorna el índice del elemento encontrado
    } else if (arr[medio] < elemento) {
      inicio = medio + 1;
    } else {
      fin = medio - 1;
    }
  }
  return -1; // Retorna -1 si el elemento no se encuentra en el arreglo
}

const arregloOrdenado = [2, 3, 5, 6, 8, 10];
const elementoBuscado = 6;
const indice = busquedaBinaria(arregloOrdenado, elementoBuscado);
console.log(`El elemento ${elementoBuscado} se encuentra en el índice ${indice}.`);


Sabendo disso, podemos dizer que o Algoritmo de Pesquisa Linear é útil quando trabalhamos com um conjunto de dados pequeno ou não ordenado e nenhuma informação adicional sobre a localização do elemento está disponível.

Porém, nos casos em que os dados são ordenados, o Algoritmo de Pesquisa Binária pode ser muito mais eficiente, pois reduz o intervalo de pesquisa pela metade em cada iteração.

Algoritmos de Classificação

Algoritmos de Classificação são técnicas usadas para organizar os elementos de uma lista ou array em uma ordem específica. Em JavaScript, existem vários algoritmos de classificação populares que são muito úteis para desenvolvedores. Abaixo estão alguns deles:

Algoritmo de Classificação por Bolha

O algoritmo de bolha é um método que funciona para ordenar algoritmos em ordem crescente e decrescente. Com este algoritmo, iteramos e trocamos pares até movermos o elemento maior (ou o menor, dependendo do que queremos alcançar) para o final da lista. Feito isso, passamos a mover o segundo maior (ou segundo menor) elemento para a penúltima posição da lista e assim iremos “borbulhar” até atingirmos o arranjo ordenado que procuramos.

Abaixo está uma ilustração que demonstra como o algoritmo funciona em sua primeira iteração, sendo [5, 3, 8, 2, 6] o arranjo original. Neste caso nosso objetivo seria ordenar o algoritmo em ordem crescente.


Conforme mencionado acima, nosso objetivo na primeira iteração é mover o maior elemento para o final. Neste caso, nosso maior elemento é 8. Na próxima iteração onde i=1 nosso objetivo seria mover 6 (o segundo maior número) para a penúltima posição, que neste caso já está lá.

Já temos uma ideia de como o algoritmo funciona, mas como seria no código JavaScript?

function ordenamientoBurbuja(arr) {
  const n = arr.length;
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {

        // Intercambio de elementos

        const temp = arr[j]
        arr[j] = arr[j + 1]

        arr[j + 1] = temp
      }
    }
  }
  return arr;
}

const arreglo = [5, 3, 8, 2, 6];
const arregloOrdenado = ordenamientoBurbuja(arreglo);
console.log(arregloOrdenado); // Output: [2, 3, 5, 6, 8]



É importante notar que o algoritmo bubble sort não é eficiente para grandes conjuntos de dados, uma vez que sua complexidade é quadrática (O(n^2)). No entanto, é um algoritmo útil para aprender e compreender os fundamentos dos algoritmos de classificação.

Vale lembrar que existem outros algoritmos mais eficientes, como o Quick Sort Algorithm, utilizado em situações onde é necessário maior desempenho na ordenação de grandes conjuntos de dados.

Algoritmo de Classificação Rápida (Quicksort)

Use a abordagem de "dividir para conquistar" para classificar a lista. Este algoritmo divide a lista em subconjuntos menores e classifica cada subconjunto recursivamente. É um dos mais eficientes e amplamente utilizados para organização. Aqui está um exemplo de implementação:

function ordenamientoRapido(arr) {
  if (arr.length <= 1) {
    return arr;
  }

  const pivot = arr[arr.length - 1]; 

  // En muchos casos también se utiliza pivot = arr[0]


  let menores = [];
  let mayores = [];

  for (let i = 0; i < arr.length; i++) {
    if (arr[i] < pivot) {
      menores.push(arr[i]);
    } else {
      mayores.push(arr[i]);
    }
  }

  return [...ordenamientoRapido(menores), pivot, ...ordenamientoRapido(mayores)];
}

const arreglo = [5, 3, 8, 2, 6];
const arregloOrdenado = ordenamientoRapido(arreglo);
console.log(arregloOrdenado); // Output: [2, 3, 5, 6, 8]



Algoritmo de Classificação Notation (Notation Sort)

Também conhecido como Notation Sort, é um algoritmo de classificação não convencional. Ao contrário de outros algoritmos que dependem de comparações diretas entre elementos, o Notation Sort usa uma notação especial para determinar a ordem dos elementos na lista. Embora não seja um algoritmo prático em termos de eficiência e desempenho, é interessante explorar o seu funcionamento e as suas possíveis utilizações em situações particulares.

O Algoritmo de Classificação de Notação baseia-se na atribuição de um valor numérico ou rótulo a cada elemento da lista a ser classificada. Esses valores numéricos ou rótulos são gerados de alguma forma específica, não necessariamente relacionada ao valor real dos elementos. Um processo de classificação é então realizado usando esses valores atribuídos, resultando em uma nova ordenação dos elementos.

A ideia do algoritmo de classificação Notation é que a atribuição de valores ou rótulos não dependa de comparações diretas entre elementos, mas de uma série de regras ou critérios previamente estabelecidos. Estes critérios podem ser arbitrários ou baseados em algum aspecto particular dos elementos. Por exemplo, os valores podem ser atribuídos com base no número de vogais em uma sequência de texto ou com base no comprimento das palavras.

Vejamos um exemplo de implementação do algoritmo de classificação de notação em JavaScript usando uma atribuição de valor baseada no comprimento da palavra:

function notationSort(arr) {
  const sortedIndices = arr
    .map((value, index) => index)
    .sort((a, b) => {
      const lengthA = arr[a].length;
      const lengthB = arr[b].length;
      return lengthA - lengthB;
    });

  const result = [];
  for (const index of sortedIndices) {
    result.push(arr[index]);
  }
 
  return result;
}

// Ejemplo de uso
const palabras = ["manzana", "perro", "gato", "banana"];
const palabrasOrdenadas = notationSort(palabras);
console.log(palabrasOrdenadas); // Output: ["gato", "perro", "banana", "manzana"]

Neste exemplo, temos um array de palavras confusas ["maçã", "cachorro", "gato", "banana"]. Aplicando o Algoritmo de Ordenação de Notação baseado no comprimento das palavras, obteremos o array ordenado ["gato", "cachorro", "banana", "maçã"].

Comparação de desempenho e eficiência de algoritmos de classificação

Cada algoritmo de classificação tem suas vantagens e desvantagens em termos de desempenho e eficiência. O algoritmo Bubble Sort ou de bolha, embora fácil de implementar, tende a ser lento em grandes conjuntos de dados devido à sua complexidade quadrática. Da mesma forma, o algoritmo Quicksort é mais eficiente e geralmente preferido para grandes conjuntos de dados. Por outro lado, o Algoritmo de Notação é bom para classificações mais personalizadas, não necessariamente numéricas.

No dia a dia, os desenvolvedores de JavaScript podem usar esses algoritmos para otimizar seu código em diferentes situações. Por exemplo, quando você tem um grande conjunto de dados que precisa ser classificado, o uso de algoritmos mais eficientes, como o Quick Sort, pode acelerar o processamento. Em outros casos, como quando você precisa classificar um pequeno conjunto de dados ou manter uma lista parcialmente classificada, existem outros algoritmos, como inserção ou classificação por seleção, que podem ser uma opção melhor. A escolha do algoritmo apropriado dependerá das necessidades específicas do projeto e da otimização necessária.


Conclusão

O conhecimento e a aplicação de algoritmos são essenciais para qualquer desenvolvedor JavaScript que deseja escrever código eficiente e escalável. Neste artigo, exploramos alguns dos algoritmos mais comumente usados, algoritmos de pesquisa e classificação. Além disso, destacamos sua aplicação em situações reais e como podem melhorar o desempenho de suas aplicações. Continue praticando e explorando esses conceitos, pois dominá-los tornará você um desenvolvedor mais competente e permitirá que você resolva problemas de maneira mais eficaz.

Lembre-se de que este artigo apenas arranha a superfície dos algoritmos e estruturas de dados. Encorajo você a continuar aprendendo, pesquisando e aplicando esses conceitos em seus projetos. Explore as possibilidades e desafie-se a se tornar um/a especialista em algoritmos e estruturas de dados com JavaScript!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.