Úvod
Řazení je základní operace v informatice, která zahrnuje uspořádání prvků do určitého pořadí, jako je číselné nebo abecední pořadí. Byly vyvinuty různé třídicí algoritmy, každý s ukazateli času a účinnosti. Lineární časové třídění je podmnožinou třídicích algoritmů s významnou výhodou: mohou třídit danou sadu prvků v lineárním čase, doba běhu se lineárně zvyšuje se vstupní velikostí.
Nejznámějším algoritmem lineárního řazení v čase je sestupné řazení. Výpočtové třídění je zvláště účinné, když je rozsah vstupních prvků známý a relativně malý. To eliminuje potřebu porovnávat prvky, což je hlavní časově náročná operace v mnoha dalších třídicích algoritmech. Pomocí znalostí vstupní domény dosahuje výpočetní třídění lineární časové složitosti. Číselné řazení nejprve prohledá vstupní pole a určí počet každého prvku. Tato čísla pak použije k výpočtu správných poloh prvků v uspořádané výsledkové tabulce. Algoritmus se skládá z následujících kroků:
- Chcete-li určit rozsah, identifikujte minimální a maximální hodnoty vstupního pole.
- Vytvořte list inicializovaný s velikostí rozsahu a nulami.
- Iterujte vstupní pole a zvyšujte každý nalezený prvek.
- Upravte list výpočtem kumulativního součtu, abyste získali správné pozice pro každý prvek.
- Vytvořte výstupní pole stejné velikosti jako vstupní pole.
- Znovu přesuňte vstupní pole a umístěte každý prvek na správnou pozici ve výstupním poli na základě listu.
- Výsledná tabulka nyní obsahuje seřazené prvky.
Hlavní výhodou sestupného řazení je, že dosahuje lineární časové složitosti O(n), díky čemuž je velmi efektivní pro velké vstupní velikosti. Jeho použitelnost je však omezena na scénáře, kde je výběr vstupních prvků předem znám a je relativně malý.
Je důležité poznamenat, že jiné třídící algoritmy, jako je quicksort nebo merge, mají typicky časovou složitost O(n log n), což je považováno za efektivní pro mnoho praktických aplikací. Algoritmy lineárního časového třídění, jako je numerické třídění, poskytují alternativu, když určitá omezení nebo vlastnosti vstupu umožňují použití lineární časové složitosti.
Dějiny
Algoritmy lineárního třídění mají v počítačové vědě bohatou historii. Vývoj lineárního časového uspořádání lze vysledovat do poloviny 20. století a významné byly příspěvky vědců a matematiků. Jedním z prvních lineárních algoritmů třídění podle času je třídění segmentů, které navrhl Harold H. Seward v roce 1954. Třídění segmentů rozděluje vstupní prvky do konečného počtu segmentů a poté třídí každý segment samostatně. Tento algoritmus má lineární časovou složitost, pokud je rozložení vstupních prvků relativně rovnoměrné.
V roce 1959 Kenneth E. Iverson představil radixový algoritmus, který dosahuje lineární časové složitosti. Radix řadí prvky podle jejich čísel nebo znamének od nejméně významných po nejvýznamnější. Využívá robustní třídicí algoritmy, jako je numerické nebo skupinové třídění, k řazení prvků na každé pozici číslic. Radixové třídění se stalo populární v éře děrných štítků a raných počítačových systémů. Nejznámějším lineárním algoritmem třídění podle času je však výčet, který představili Harold H. Seward a Peter Elias v roce 1954 a později nezávisle znovuobjevený Haroldem H. 'Bobby' Johnsonem v roce 1961. Numerickému třídění se dostalo značné pozornosti.
To je zvláště účinné, když je rozsah vstupních prvků známý a relativně malý. Historie lineárního třídění času pokračovala vývojem dalších specializovaných algoritmů. Například v roce 1987 navrhl Hanan Samet třídění binárních distribučních stromů, lineární algoritmus časového třídění pro vícerozměrná data. V průběhu let výzkumníci pokračovali ve studiu a zdokonalování lineárních plánovacích algoritmů se zaměřením na konkrétní scénáře a omezení. Přestože algoritmy jako quicksort a merge jsou pro svou efektivitu ve více scénářích více používány, algoritmy třídění v lineárním čase poskytují cenné alternativy, když určité okolnosti umožňují využít složitost lineárního času. Obecně se historie lineárního třídění v čase vyznačuje hledáním účinných algoritmů, které dokážou třídit velké soubory dat v lineárním čase, čímž překonávají omezení třídicích algoritmů založených na porovnání. Příspěvky různých výzkumníků připravily cestu pro vývoj a pochopení těchto specializovaných třídicích technik.
Typy lineárního časového třídění
Existuje několik různých lineárních algoritmů řazení v čase. Dva hlavní typy jsou algoritmy založené na počtu a algoritmy založené na radixu. Zde jsou nejběžnější algoritmy lineárního řazení podle času, klasifikované na základě následujících typů:
Algoritmy založené na počítání
Algoritmy založené na Radixu
Výhody lineárního časového třídění
Algoritmy lineárního časového třídění, jako je numerické třídění, nabízejí ve specifických scénářích několik výhod.
Nevýhody lineárního časového třídění
Přestože lineární plánovací algoritmy mají své výhody, mají také určitá omezení a nevýhody:
Při výběru třídícího algoritmu je nezbytné pečlivě zvážit specifika vstupních dat a požadavky třídícího problému. I když lineární plánovací algoritmy nabízejí výhody ve specifických scénářích, jen někdy jsou tou nejvhodnější nebo nejúčinnější volbou.
Aplikace algoritmů lineárního řazení v čase
Algoritmy lineárního třídění jsou účinné a mají mnoho aplikací v různých oblastech. Zde jsou některé typické aplikace lineárního časového řádu:
Implementace lineárního časového třídění v C++
Zde je příklad programu implementujícího Counting Sort, což je lineární algoritmus řazení podle času:
#include #include using namespace std; void countingSort(vector& 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's maximum value to determine the worksheet's size. It then counts each element's occurrence and calculates the worksheet'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();>
To znamená, že vstupní pole bylo seřazeno vzestupně pomocí algoritmu Counting Sort, což vedlo k seřazenému poli [1, 2, 2, 3, 3, 4, 8].
V tomto programu C++ přebírá funkce řazení počítání odkaz na vektor arr a spouští rutinu řazení počítání. Zjistí maximální hodnotu tabulky a určí velikost listu. Potom spočítá výskyt každého prvku a vypočítá součet prefixů listu. Poté vytvoří výsledný vektor a seřadí prvky podle listu. Nakonec zkopíruje seřazené prvky zpět do původního pole. V primární funkci je ukázkové pole {4, 2, 2, 8, 3, 3, 1} seřazeno podle výčtového třídícího algoritmu a vytištěno jako seřazená matice. Všimněte si, že program používá knihovny pro práci s vektory a nalezení maximálního prvku pole pomocí funkce max_element.