logo

Classificação de tempo linear

Introdução

A classificação é uma operação essencial na ciência da computação que envolve organizar os elementos em uma ordem específica, como ordem numérica ou alfabética. Vários algoritmos de classificação foram desenvolvidos, cada um com indicadores de tempo e eficiência. A classificação em tempo linear é um subconjunto de algoritmos de classificação com uma vantagem significativa: eles podem classificar um determinado conjunto de elementos em tempo linear, o tempo de execução aumenta linearmente com o tamanho da entrada.

meulivericket

O algoritmo de classificação de tempo linear mais conhecido é a classificação descendente. A classificação computacional é particularmente eficiente quando a gama de elementos de entrada é conhecida e relativamente pequena. Isso elimina a necessidade de comparar elementos, a principal operação demorada em muitos outros algoritmos de classificação. Usando o conhecimento do domínio de entrada, a classificação computacional atinge a complexidade do tempo linear. Uma classificação numérica primeiro verifica a matriz de entrada para determinar a contagem de cada elemento. Em seguida, utiliza esses números para calcular as posições corretas dos elementos na tabela de resultados ordenados. O algoritmo consiste nas seguintes etapas:

  1. Para determinar o intervalo, identifique os valores mínimo e máximo da matriz de entrada.
  2. Crie uma planilha inicializada com o tamanho do intervalo e zeros.
  3. Itere sobre a matriz de entrada e incremente cada elemento encontrado.
  4. Modifique a planilha calculando o total acumulado para obter as posições corretas para cada elemento.
  5. Crie uma matriz de saída do mesmo tamanho da matriz de entrada.
  6. Mova a matriz de entrada novamente, colocando cada elemento na posição correta na matriz de saída com base na planilha.
  7. A tabela de resultados agora contém elementos classificados.
Classificação de tempo linear

A principal vantagem da classificação descendente é que ela atinge uma complexidade de tempo linear de O(n), o que a torna muito eficiente para grandes tamanhos de entrada. Contudo, a sua aplicabilidade é limitada a cenários onde a escolha dos elementos de entrada é conhecida antecipadamente e relativamente pequena.

É importante notar que outros algoritmos de ordenação, como quicksort ou merge, normalmente possuem uma complexidade de tempo de O(n log n), que é considerada eficiente para muitas aplicações práticas. Algoritmos de classificação de tempo linear, como classificação numérica, fornecem uma alternativa quando certas restrições ou propriedades da entrada permitem o uso de complexidade de tempo linear.

História

Algoritmos de classificação de tempo linear têm uma história rica na ciência da computação. O desenvolvimento da ordem do tempo linear remonta a meados do século 20, e as contribuições de cientistas e matemáticos foram significativas. Um dos primeiros algoritmos de classificação de tempo linear é o bucket sort, proposto por Harold H. Seward em 1954. Um bucket sort divide os elementos de entrada em um número finito de buckets e então classifica cada bucket separadamente. Este algoritmo possui complexidade de tempo linear se a distribuição dos elementos de entrada for relativamente uniforme.

Em 1959, Kenneth E. Iverson introduziu um algoritmo radix que atinge complexidade de tempo linear. Radix classifica os elementos por seus números ou sinais, do menos significativo ao mais significativo. Ele usa algoritmos de classificação robustos, como classificação numérica ou de intervalo, para classificar os elementos em cada local de dígito. A classificação Radix tornou-se popular na era dos cartões perfurados e dos primeiros sistemas de computador. No entanto, o algoritmo de classificação de tempo linear mais conhecido é uma enumeração, introduzida por Harold H. Seward e Peter Elias em 1954 e mais tarde redescoberta de forma independente por Harold H. 'Bobby' Johnson em 1961. A classificação numérica recebeu atenção considerável.

Isto é particularmente eficaz quando a gama de elementos de entrada é conhecida e relativamente pequena. A história da classificação linear no tempo continuou com o desenvolvimento de outros algoritmos especializados. Por exemplo, em 1987, Hanan Samet propôs a classificação em árvore de distribuição binária, um algoritmo de classificação linear no tempo para dados multidimensionais. Ao longo dos anos, os pesquisadores continuaram a estudar e melhorar algoritmos de escalonamento linear, concentrando-se em cenários e restrições específicas. Embora algoritmos como quicksort e merge sejam mais amplamente usados ​​por sua eficiência em mais cenários, os algoritmos de classificação em tempo linear fornecem alternativas valiosas quando certas circunstâncias permitem que a complexidade do tempo linear seja explorada. Em geral, a história da ordenação em tempo linear é caracterizada pela busca por algoritmos eficientes que possam ordenar grandes conjuntos de dados em tempo linear, superando as limitações dos algoritmos de ordenação baseados em comparação. As contribuições de vários pesquisadores abriram caminho para o desenvolvimento e compreensão dessas técnicas especializadas de classificação.

Tipos de classificação de tempo linear

Existem vários algoritmos diferentes de classificação de tempo linear. Os dois tipos principais são algoritmos baseados em contagem e algoritmos baseados em raiz. Aqui estão os algoritmos de classificação de tempo linear mais comuns, classificados com base nos seguintes tipos:

Algoritmos Baseados em Contagem

    Classificação baseada em contagem:Counting-Based é um algoritmo de classificação não comparativo. Ele conta a ocorrência de cada elemento específico na matriz de entrada e usa essas informações para determinar a posição correta de cada elemento na matriz de saída classificada. A classificação baseada em contagem assume que os elementos de entrada são inteiros ou podem ser adicionados a inteiros.

Algoritmos Baseados em Radix

    Classificar raiz:Radix Sort é um algoritmo de classificação não baseado em comparação que classifica os elementos por seus números ou caracteres. Ele conta cada número ou sinal nos elementos, do número menos significativo ao mais significativo. A classificação radical assume que os elementos de entrada são inteiros ou strings.Classificação de intervalo:Bucket Sort é uma variante do Radix Sort que divide os elementos em grupos fixos com base em seu intervalo ou distribuição. Cada segmento é classificado separadamente usando um algoritmo de classificação diferente ou classificação bin recursivamente.Classificação de raiz MSD (dígito mais significativo):MSD Radix Sort é uma variante do radix sort que começa a classificar os elementos com base em seus mais significativos. Ele divide recursivamente os elementos em subgrupos com base no valor do número atual e aplica o MSD Radix Sort a cada subgrupo até que todos os números tenham sido contados.Classificação de raiz LSD (dígito menos significativo):LSD Radix Sort é outra variante que começa a classificar os elementos com base em seus menos significativos. Ele classifica recursivamente os elementos com base em cada número, da extrema direita para a esquerda, produzindo um resultado classificado. Os algoritmos de classificação baseados em contagem e baseados em raiz alcançam complexidade de tempo linear explorando propriedades específicas dos elementos de entrada, como seu intervalo ou estrutura representacional (por exemplo, números ou caracteres). Contudo, a sua aplicabilidade pode variar dependendo das características dos dados de entrada.

Vantagens da classificação de tempo linear

Algoritmos de classificação linear em tempo, como classificação numérica, oferecem diversas vantagens em cenários específicos.

    Eficiente para tamanhos de entrada grandes:A complexidade de tempo dos algoritmos de classificação de tempo linear é O(n), o que significa que o tempo de execução aumenta linearmente com o tamanho da entrada. Isso os torna muito eficientes para grandes conjuntos de dados em comparação com algoritmos de classificação baseados em comparação, como quicksort ou algoritmos de mesclagem, que normalmente têm uma complexidade de tempo de O(n log n).Nenhuma operação de comparação:Algoritmos de classificação em tempo linear, como classificação por enumeração, não dependem de comparação elementar. Em vez disso, eles usam atributos ou informações específicas sobre os elementos de entrada, como sua extensão ou distribuição. Esse recurso os torna vantajosos quando o custo da comparação é alto, como no caso de objetos complexos ou operações de comparação caras.Adequação a propriedades de entrada específicas:Algoritmos de classificação em tempo linear geralmente possuem requisitos ou suposições específicas sobre os elementos de entrada. Por exemplo, para calcular uma ordem de classificação, você precisa conhecer antecipadamente o intervalo de elementos de entrada. Quando essas condições são atendidas, os algoritmos de classificação em tempo linear podem oferecer vantagens significativas de desempenho em relação aos algoritmos de classificação geral.Classificação estável:Muitos algoritmos de classificação em tempo linear, incluindo classificação numérica e radix, são inerentemente estáveis. Consistência significa que elementos com chaves ou valores duplicados mantêm a ordem relativa na saída classificada. Isso pode ser crítico quando a classificação de objetos ou registros com múltiplos atributos ou quando é essencial preservar a ordem original de elementos de igual valor.Fácil de usar:Algoritmos de classificação de tempo linear, como classificação de enumeração, costumam ser relativamente fáceis de implementar em comparação com algoritmos de classificação baseados em comparação mais complexos. Eles podem ser mais fáceis de entender e depurar, tornando-os adequados para situações onde simplicidade e clareza são desejadas.

Desvantagens da classificação de tempo linear

Embora os algoritmos de escalonamento linear tenham suas vantagens, eles também apresentam certas limitações e desvantagens:

    Requisitos de entrada restritivos:Algoritmos de classificação de tempo linear geralmente têm requisitos ou suposições específicas sobre os elementos de entrada. Por exemplo, para calcular uma ordem de classificação, você precisa conhecer antecipadamente o intervalo de elementos de entrada. Esta restrição limita a sua aplicabilidade a situações em que estas condições sejam satisfeitas. Os requisitos de memória podem tornar-se impraticáveis ​​ou exceder os recursos disponíveis se o intervalo for extenso ou desconhecido.Requisitos adicionais de espaço:Alguns algoritmos de classificação linear no tempo, como a classificação numérica, requerem espaço adicional para armazenar outras matrizes ou estruturas de dados. O espaço necessário é muitas vezes proporcional ao número de elementos de entrada. Isto pode ser uma desvantagem quando o uso de memória é um problema, especialmente ao lidar com grandes conjuntos de dados ou recursos de memória limitados.Falta de versatilidade:Algoritmos de classificação de tempo linear são algoritmos especializados projetados para cenários ou restrições específicas. Eles podem precisar ser mais adequados e eficientes para tarefas gerais de classificação ou diferentes distribuições de entradas. Algoritmos de classificação baseados em comparação, como quicksort ou merge, são mais versáteis e podem lidar com uma faixa mais ampla de entradas.Ineficiente para intervalos pequenos ou dados esparsos:Algoritmos de classificação em tempo linear, como enumeração, são mais eficientes quando o intervalo de elementos de entrada é pequeno e densamente distribuído. Se o intervalo for extenso ou os dados forem esparsos (ou seja, apenas alguns valores distintos), o algoritmo pode economizar tempo e esforço no processamento de porções vazias ou pouco povoadas do intervalo de entrada.Limitado a tipos de dados específicos:Algoritmos de classificação em tempo linear, como classificação de enumeração, são projetados principalmente para classificar números inteiros não negativos ou objetos de valor-chave. Eles podem não ser adequados para classificar outros tipos de dados, como números de ponto flutuante, strings ou estruturas de dados complexas. A adaptação de algoritmos de classificação de tempo linear para lidar com diferentes tipos de dados ou funções de comparação personalizadas pode exigir pré-processamento ou modificações adicionais.

Ao escolher um algoritmo de classificação, é essencial considerar cuidadosamente as especificidades dos dados de entrada e os requisitos do problema de classificação. Embora os algoritmos de escalonamento linear ofereçam vantagens em cenários específicos, eles são apenas algumas vezes a escolha mais apropriada ou eficiente.

Aplicações de algoritmos de classificação de tempo linear

Algoritmos de classificação em tempo linear são eficientes e têm muitas aplicações em vários campos. Aqui estão algumas aplicações típicas de ordem de tempo linear:

    Classificando números inteiros de pequeno intervalo:Algoritmos de classificação de tempo linear, como classificação de contagem e classificação de base, são ideais para classificar matrizes de números inteiros quando o intervalo de valores é. Esses algoritmos atingem complexidade de tempo linear fazendo suposições sobre os dados de entrada, permitindo-lhes ignorar a classificação baseada em comparação.Classificação de strings:Algoritmos de classificação em tempo linear também podem ser aplicados para classificar strings com eficiência. Ao obter propriedades exclusivas de strings, como comprimento ou caracteres, algoritmos como Radix Sort podem atingir complexidade de tempo linear ao classificar strings.Funções de banco de dados:A classificação é uma função essencial dos algoritmos de classificação em tempo linear que podem classificar com eficiência grandes conjuntos de dados com base em colunas ou campos específicos. Isso permite um processamento de consultas mais rápido e melhor desempenho nas operações de banco de dados.Criando Histogramas:Os histogramas são essenciais para várias tarefas estatísticas e de análise de dados. Algoritmos de classificação linear em tempo, como classificação numérica, podem gerar histogramas contando eficientemente as ocorrências de elementos em um conjunto de dados.Classificação externa:A técnica de classificação externa é usada em cenários onde os dados não cabem inteiramente na memória. Algoritmos de classificação de tempo linear, como classificação de base externa ou classificação de contagem externa, podem classificar com eficiência grandes conjuntos de dados armazenados em disco ou outros dispositivos de armazenamento externos.Agendamento de eventos:Algoritmos de classificação de tempo linear podem agendar eventos com base em seus horários de início ou término. A classificação de eventos em ordem crescente facilita a identificação de conflitos, períodos sobrepostos ou a localização do próximo período disponível.Analisando arquivos de log:A análise de arquivos de log é uma tarefa comum na administração e depuração do sistema. Algoritmos de classificação linear de tempo podem ser usados ​​para classificar logs com base em carimbos de data/hora, facilitando a identificação de padrões, anomalias ou a busca por eventos específicos.Compressão de dados:A classificação desempenha um papel essencial em várias técnicas de compactação de dados. Algoritmos como Burrows-Wheeler Transform (BWT) ou Move-To-Front Transform (MTF) dependem da ordenação de tempo linear para reorganizar os dados e melhorar a eficiência da compactação. Estes são apenas alguns exemplos de aplicações de algoritmos de classificação linear em tempo.

Implementação de classificação de tempo linear em C++

Aqui está um exemplo de um programa que implementa Counting Sort, que é um algoritmo de classificação de tempo linear:

 #include #include using namespace std; void countingSort(vector&amp; arr) { // Find the maximum element in the array int max_val = *max_element(arr.begin(), arr.end()); // Create a count array to store the count of each element vector count(max_val + 1, 0); // Count the occurrences of each element for (int num : arr) { count[num]++; } // Compute the prefix sum for (int i = 1; i <count.size(); i++) { count[i] +="count[i" - 1]; } create a sorted output array vector output(arr.size()); place the elements in order for (int i="arr.size()" 1;>= 0; i--) { output[count[arr[i]] - 1] = arr[i]; count[arr[i]]--; } // Copy the sorted elements back to the original array for (int i = 0; i <arr.size(); i++) { arr[i]="output[i];" } int main() vector arr="{4," 2, 8, 3, 1}; sort the array using counting countingsort(arr); print sorted cout << 'sorted array: '; for (int num : arr) ' endl; return 0; < pre> <p> <strong>Sample Output</strong> </p> <pre> Sorted array: 1 2 2 3 3 4 8 </pre> <p>This indicates that the input array has been sorted in ascending order using the Counting Sort algorithm, resulting in the sorted array [1, 2, 2, 3, 3, 4, 8].</p> <p>In this C++ program, the counting sort function takes a reference to the vector arr and runs the counting sort routine. It finds the table&apos;s maximum value to determine the worksheet&apos;s size. It then counts each element&apos;s occurrence and calculates the worksheet&apos;s prefix sum. Then, it creates a result vector and puts the elements in order according to the worksheet. Finally, it copies the sorted elements back into the original array. In the primary function, the example array {4, 2, 2, 8, 3, 3, 1} is sorted by the enumeration sort algorithm and printed as a sorted matrix. Note that the program uses libraries to work with vectors and find the maximum element of an array using the max_element function.</p> <hr></arr.size();></count.size();>

Isso indica que a matriz de entrada foi classificada em ordem crescente usando o algoritmo Counting Sort, resultando na matriz classificada [1, 2, 2, 3, 3, 4, 8].

Neste programa C++, a função de classificação de contagem faz uma referência ao vetor arr e executa a rotina de classificação de contagem. Encontra o valor máximo da tabela para determinar o tamanho da planilha. Em seguida, conta a ocorrência de cada elemento e calcula a soma dos prefixos da planilha. Em seguida, ele cria um vetor de resultado e ordena os elementos de acordo com a planilha. Finalmente, ele copia os elementos classificados de volta ao array original. Na função primária, a matriz de exemplo {4, 2, 2, 8, 3, 3, 1} é classificada pelo algoritmo de classificação de enumeração e impressa como uma matriz classificada. Observe que o programa utiliza bibliotecas para trabalhar com vetores e encontrar o elemento máximo de um array usando a função max_element.