logo

Lineární časové třídění

Ú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ů:

  1. Chcete-li určit rozsah, identifikujte minimální a maximální hodnoty vstupního pole.
  2. Vytvořte list inicializovaný s velikostí rozsahu a nulami.
  3. Iterujte vstupní pole a zvyšujte každý nalezený prvek.
  4. Upravte list výpočtem kumulativního součtu, abyste získali správné pozice pro každý prvek.
  5. Vytvořte výstupní pole stejné velikosti jako vstupní pole.
  6. 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.
  7. Výsledná tabulka nyní obsahuje seřazené prvky.
Lineární časové třídění

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í

    Řazení podle počítání:Counting-Based je nesrovnávací třídicí algoritmus. Počítá výskyt každého konkrétního prvku ve vstupním poli a používá tyto informace k určení správné polohy každého prvku v seřazeném výstupním poli. Řazení podle počítání předpokládá, že vstupní prvky jsou celá čísla nebo je lze k celým číslům přidat.

Algoritmy založené na Radixu

    Seřadit Radix:Radix Sort je třídicí algoritmus nezaložený na porovnání, který třídí prvky podle jejich čísel nebo znaků. Počítá každé číslo nebo znaménko v prvcích od nejméně významného čísla po nejvýznamnější. Radikální řazení předpokládá, že vstupní prvky jsou celá čísla nebo řetězce.Řazení kbelíku:Bucket Sort je varianta Radix Sort, která rozděluje prvky do pevných skupin na základě jejich rozsahu nebo rozložení. Každý segment je tříděn samostatně pomocí jiného třídícího algoritmu nebo rekurzivně bin-sort.MSD (nejvýznamnější číslice) Radix řazení:MSD Radix Sort je varianta radixového třídění, která začíná třídit prvky na základě jejich nejvýznamnějšího. Rekurzivně rozděluje prvky do podskupin na základě hodnoty aktuálního čísla a aplikuje MSD Radix Sort na každou podskupinu, dokud nejsou spočítána všechna čísla.LSD (nejméně významná číslice) Radixové řazení:LSD Radix Sort je další variantou, která začíná třídit prvky na základě jejich nejméně významného. Rekurzivně třídí prvky na základě každého čísla od nejvíce vpravo k nejvíce vlevo, čímž se získá seřazený výsledek. Algoritmy řazení založené na počtu i na kořenech dosahují lineární časové složitosti využitím specifických vlastností vstupních prvků, jako je jejich rozsah nebo reprezentativní struktura (např. čísla nebo znaky). Jejich použitelnost se však může lišit v závislosti na vlastnostech vstupních dat.

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.

    Efektivní pro velké vstupní velikosti:Časová složitost algoritmů lineárního časového třídění je O(n), což znamená, že doba běhu roste lineárně s velikostí vstupu. Díky tomu jsou velmi efektivní pro velké soubory dat ve srovnání s třídicími algoritmy založenými na porovnání, jako jsou algoritmy rychlého třídění nebo slučování, které mají obvykle časovou složitost O(n log n).Žádné srovnávací operace:Algoritmy třídění v lineárním čase, jako je výčtové třídění, se nespoléhají na elementární srovnání Místo toho používají specifické atributy nebo informace o vstupních prvcích, jako je jejich rozsah nebo distribuce. Tato vlastnost je činí výhodnými, když jsou náklady na porovnávání vysoké, například u složitých objektů nebo drahých porovnávacích operací.Vhodnost pro konkrétní vstupní vlastnosti:Algoritmy třídění v lineárním čase mají často specifické požadavky nebo předpoklady ohledně vstupních prvků. Chcete-li například vypočítat pořadí řazení, musíte předem znát rozsah vstupních prvků. Jsou-li splněny tyto podmínky, algoritmy lineárního třídění mohou nabídnout významné výkonnostní výhody oproti obecným algoritmům třídění.Stabilní řazení:Mnoho algoritmů třídění v lineárním čase, včetně numerického a radixového třídění, je ze své podstaty stabilní. Konzistence znamená, že prvky s duplicitními klíči nebo hodnotami si zachovávají relativní pořadí v seřazeném výstupu. To může být kritické, když třídíte objekty nebo záznamy s více atributy nebo když je nezbytné zachovat původní pořadí prvků stejné hodnoty.Snadnost použití:Algoritmy lineárního třídění, jako je výčtové třídění, jsou často relativně snadno implementovatelné ve srovnání se složitějšími třídicími algoritmy založenými na porovnání. Mohou být snáze pochopitelné a laditelné, takže jsou vhodné pro situace, kde je požadována jednoduchost a jasnost.

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:

    Omezující vstupní požadavky:Algoritmy lineárního třídění mají často specifické požadavky nebo předpoklady ohledně vstupních prvků. Chcete-li například vypočítat pořadí řazení, musíte předem znát rozsah vstupních prvků. Toto omezení omezuje jejich použitelnost na situace, kdy jsou tyto podmínky splněny. Požadavky na paměť se mohou stát nepraktickými nebo překročit dostupné zdroje, pokud je rozsah rozsáhlý nebo neznámý.Další požadavky na prostor:Některé algoritmy lineárního časového třídění, jako je numerické třídění, vyžadují další prostor pro uložení dalších polí nebo datových struktur. Potřebný prostor je často úměrný počtu vstupních prvků. To může být nevýhodou, když je problémem využití paměti, zejména při práci s velkými datovými sadami nebo omezenými paměťovými prostředky.Nedostatek všestrannosti:Algoritmy lineárního třídění jsou specializované algoritmy navržené pro specifické scénáře nebo omezení. Možná budou muset být vhodnější a efektivnější pro obecné úkoly třídění nebo různé distribuce vstupů. Algoritmy třídění založené na porovnání, jako je rychlé třídění nebo sloučení, jsou všestrannější a dokážou zpracovat širší rozsah vstupního rozsahu.Neefektivní pro malé rozsahy nebo řídká data:Algoritmy třídění v lineárním čase, jako je výčet, jsou nejúčinnější, když je rozsah vstupních prvků malý a hustě distribuovaný. Pokud je rozsah rozsáhlý nebo jsou data řídká (tj. pouze několik odlišných hodnot), může algoritmus ušetřit čas a úsilí při zpracování prázdných nebo řídce zaplněných částí vstupního rozsahu.Omezeno na konkrétní typy dat:Algoritmy třídění v lineárním čase, jako je třídění výčtu, jsou primárně navrženy pro třídění nezáporných celých čísel nebo objektů klíč–hodnota. Nemusí být vhodné pro řazení jiných datových typů, jako jsou čísla s plovoucí desetinnou čárkou, řetězce nebo složité datové struktury. Přizpůsobení algoritmů lineárního třídění podle času pro zpracování různých typů dat nebo vlastních porovnávacích funkcí může vyžadovat dodatečné předběžné zpracování nebo úpravy.

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:

    Třídění malých rozsahů celých čísel:Algoritmy lineárního třídění podle času, jako je count sort a radix sort, jsou ideální pro třídění polí celých čísel, když rozsah hodnot je Tyto algoritmy dosahují lineární časové složitosti tím, že vytvářejí předpoklady o vstupních datech, což jim umožňuje obejít třídění založené na porovnání.Třídění řetězců:K efektivnímu třídění řetězců lze také použít lineární algoritmy třídění. Díky jedinečným vlastnostem řetězců, jako je jejich délka nebo znaky, mohou algoritmy jako Radix Sort dosáhnout lineární časové složitosti při třídění řetězců.Funkce databáze:Třídění je základní funkcí lineárních algoritmů třídění v čase, které mohou efektivně třídit velké soubory dat na základě konkrétních sloupců nebo polí. To umožňuje rychlejší zpracování dotazů a lepší výkon v databázových operacích.Vytváření histogramů:Histogramy jsou nezbytné pro různé statistické úlohy a úlohy analýzy dat. Algoritmy lineárního časového třídění, jako je numerické třídění, mohou generovat histogramy efektivním počítáním výskytů prvků v datové sadě.Externí řazení:Technika externího třídění se používá ve scénářích, kde se data nevejdou celá do paměti. Algoritmy lineárního časového třídění, jako je External Radix Sort nebo External Counting Sort, mohou efektivně třídit velké soubory dat uložené na disku nebo jiných externích úložných zařízeních.Plánování akce:Algoritmy lineárního třídění mohou naplánovat události na základě jejich časů začátku nebo konce. Seřazení událostí ve vzestupném pořadí usnadňuje identifikaci konfliktů, překrývajících se období nebo nalezení dalšího dostupného období.Analýza souborů protokolu:Analýza souborů protokolu je běžným úkolem při správě a ladění systému. Algoritmy lineárního časového třídění lze použít k třídění protokolů na základě časových razítek, což usnadňuje identifikaci vzorců, anomálií nebo vyhledávání konkrétních událostí.Komprese dat:Třídění hraje zásadní roli v různých technikách komprese dat. Algoritmy, jako je Burrows-Wheeler Transform (BWT) nebo Move-To-Front Transform (MTF), spoléhají na lineární časové uspořádání pro změnu uspořádání dat za účelem zlepšení účinnosti komprese. Toto je jen několik příkladů aplikací algoritmů lineárního třídění v čase.

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&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();>

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.