Įvadas
Rūšiavimas yra esminė informatikos operacija, apimanti elementų išdėstymą tam tikra tvarka, pavyzdžiui, skaitine arba abėcėlės tvarka. Sukurti įvairūs rūšiavimo algoritmai, kurių kiekvienas turi laiko ir efektyvumo rodiklius. Linijinis laiko rūšiavimas yra rūšiavimo algoritmų poaibis, turintis didelį pranašumą: jie gali rūšiuoti tam tikrą elementų rinkinį tiesiniu laiku, vykdymo laikas tiesiškai didėja atsižvelgiant į įvesties dydį.
Geriausiai žinomas linijinio laiko rūšiavimo algoritmas yra rūšiavimas mažėjančia tvarka. Skaičiavimo rūšiavimas yra ypač efektyvus, kai žinomas įvesties elementų diapazonas ir palyginti mažas. Tai pašalina būtinybę lyginti elementus – tai pagrindinė daugelio kitų rūšiavimo algoritmų daug laiko reikalaujanti operacija. Naudojant įvesties srities žinias, skaičiavimo rūšiavimas pasiekia linijinį laiko sudėtingumą. Skaičių rūšiavimas pirmiausia nuskaito įvesties masyvą, kad nustatytų kiekvieno elemento skaičių. Tada jis naudoja šiuos skaičius, kad apskaičiuotų teisingas elementų pozicijas užsakytų rezultatų lentelėje. Algoritmas susideda iš šių žingsnių:
- Norėdami nustatyti diapazoną, nustatykite mažiausią ir didžiausią įvesties masyvo reikšmes.
- Sukurkite darbalapį, inicijuotą diapazono dydžiu ir nuliais.
- Pakartokite įvesties masyvą ir padidinkite kiekvieną rastą elementą.
- Modifikuokite darbalapį apskaičiuodami bendrą bendrą sumą, kad gautumėte teisingas kiekvieno elemento pozicijas.
- Sukurkite tokio pat dydžio išvesties masyvą kaip įvesties masyvas.
- Dar kartą perkelkite įvesties masyvą, įdėdami kiekvieną elementą į teisingą padėtį išvesties masyve pagal darbalapį.
- Rezultatų lentelėje dabar yra surūšiuoti elementai.
Pagrindinis mažėjančio rūšiavimo pranašumas yra tas, kad jis pasiekia tiesinį laiko sudėtingumą O (n), todėl jis yra labai efektyvus dideliems įvesties dydžiams. Tačiau jo pritaikymas apsiriboja scenarijais, kai įvesties elementų pasirinkimas yra žinomas iš anksto ir palyginti mažas.
Svarbu pažymėti, kad kitų rūšiavimo algoritmų, tokių kaip greitas rūšiavimas arba sujungimas, laiko sudėtingumas paprastai yra O (n log n), kuris laikomas efektyviu daugeliui praktinių pritaikymų. Linijinio laiko rūšiavimo algoritmai, tokie kaip skaitmeninis rūšiavimas, yra alternatyva, kai tam tikri įvesties apribojimai arba savybės leidžia naudoti tiesinį laiko sudėtingumą.
Istorija
Linijinio laiko rūšiavimo algoritmai turi turtingą kompiuterių mokslo istoriją. Linijinės laiko tvarkos raidą galima atsekti iki XX amžiaus vidurio, o mokslininkų ir matematikų indėlis buvo reikšmingas. Vienas iš ankstyviausių linijinio laiko rūšiavimo algoritmų yra rūšiavimas pagal segmentą, kurį 1954 m. pasiūlė Haroldas H. Sewardas. Rūšiuojant pagal segmentą įvesties elementai padalijami į baigtinį segmentų skaičių ir tada rūšiuojami kiekvienas segmentas atskirai. Šis algoritmas turi linijinį laiko sudėtingumą, jei įvesties elementų pasiskirstymas yra gana tolygus.
1959 m. Kennethas E. Iversonas pristatė radikso algoritmą, kuris pasiekia tiesinį laiko sudėtingumą. Radix rūšiuoja elementus pagal jų skaičių arba ženklus nuo mažiausiai reikšmingo iki reikšmingiausio. Elementams rūšiuoti kiekvienoje skaitmens vietoje naudojami patikimi rūšiavimo algoritmai, pvz., skaitmeninis arba segmentinis rūšiavimas. Radix rūšiavimas išpopuliarėjo perfokortelių ir ankstyvųjų kompiuterių sistemų eroje. Tačiau geriausiai žinomas linijinio laiko rūšiavimo algoritmas yra išvardijimas, kurį 1954 m. pristatė Haroldas H. Sewardas ir Peteris Eliasas, o vėliau savarankiškai iš naujo atrado Haroldas H. 'Bobby' Johnsonas 1961 m. Skaitmeniniam rūšiavimui buvo skiriamas didelis dėmesys.
Tai ypač efektyvu, kai žinomas ir palyginti mažas įvesties elementų diapazonas. Linijinio laiko rūšiavimo istorija tęsėsi kuriant kitus specializuotus algoritmus. Pavyzdžiui, 1987 m. Hananas Sametas pasiūlė dvejetainį skirstinio medžio rūšiavimą – linijinį laiko rūšiavimo algoritmą daugiamačiams duomenims. Bėgant metams mokslininkai toliau tyrinėjo ir tobulino linijinius planavimo algoritmus, sutelkdami dėmesį į konkrečius scenarijus ir apribojimus. Nors algoritmai, tokie kaip greitasis rūšiavimas ir sujungimas, yra plačiau naudojami dėl jų efektyvumo daugiau scenarijų, linijinio laiko rūšiavimo algoritmai suteikia vertingų alternatyvų, kai tam tikros aplinkybės leidžia išnaudoti tiesinio laiko sudėtingumą. Apskritai linijinio laiko rūšiavimo istorijai būdinga ieškoti efektyvių algoritmų, galinčių surūšiuoti didelius duomenų rinkinius tiesiniu laiku, įveikiant palyginimu pagrįstų rūšiavimo algoritmų apribojimus. Įvairių tyrinėtojų indėlis atvėrė kelią šių specializuotų rūšiavimo metodų kūrimui ir supratimui.
Linijinio laiko rūšiavimo tipai
Yra keli skirtingi linijinio laiko rūšiavimo algoritmai. Du pagrindiniai tipai yra skaičiavimu pagrįsti algoritmai ir radiksu pagrįsti algoritmai. Čia pateikiami dažniausiai naudojami linijinio laiko rūšiavimo algoritmai, klasifikuojami pagal šiuos tipus:
Skaičiavimu pagrįsti algoritmai
Radiksu pagrįsti algoritmai
Linijinio laiko rūšiavimo privalumai
Linijinio laiko rūšiavimo algoritmai, pvz., skaitmeninis rūšiavimas, tam tikruose scenarijuose turi keletą pranašumų.
Linijinio laiko rūšiavimo trūkumai
Nors linijiniai planavimo algoritmai turi savo privalumų, jie taip pat turi tam tikrų apribojimų ir trūkumų:
Renkantis rūšiavimo algoritmą, būtina atidžiai apsvarstyti įvesties duomenų specifiką ir rūšiavimo problemos reikalavimus. Nors linijiniai planavimo algoritmai teikia pranašumų tam tikrais atvejais, jie tik kartais yra tinkamiausias arba efektyviausias pasirinkimas.
Linijinio laiko rūšiavimo algoritmų taikymai
Linijinio laiko rūšiavimo algoritmai yra veiksmingi ir turi daug pritaikymų įvairiose srityse. Štai keletas tipiškų linijinės laiko tvarkos taikymo būdų:
Linijinio laiko rūšiavimo įgyvendinimas C++
Štai programos, įgyvendinančios skaičiavimo rūšiavimą, kuris yra linijinio laiko rūšiavimo algoritmas, pavyzdys:
#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();>
Tai rodo, kad įvesties masyvas buvo surūšiuotas didėjančia tvarka, naudojant skaičiavimo rūšiavimo algoritmą, todėl surūšiuotas masyvas [1, 2, 2, 3, 3, 4, 8].
Šioje C++ programoje skaičiavimo rūšiavimo funkcija atsižvelgia į vektorių arr ir vykdo skaičiavimo rūšiavimo tvarką. Jis randa didžiausią lentelės reikšmę, kad nustatytų darbalapio dydį. Tada jis skaičiuoja kiekvieno elemento atsiradimą ir apskaičiuoja darbalapio priešdėlio sumą. Tada jis sukuria rezultato vektorių ir sutvarko elementus pagal darbalapį. Galiausiai jis nukopijuoja surūšiuotus elementus atgal į pradinį masyvą. Pirminėje funkcijoje pavyzdinis masyvas {4, 2, 2, 8, 3, 3, 1} surūšiuojamas pagal sąrašo rūšiavimo algoritmą ir atspausdinamas kaip surūšiuota matrica. Atminkite, kad programa naudoja bibliotekas, kad galėtų dirbti su vektoriais ir rasti maksimalų masyvo elementą, naudodama funkciją max_element.