Johdanto laskentalajiin

Counting Sort on ei-vertailupohjainen lajittelualgoritmi, joka sopii hyvin kun lajittelu kokonaislukuja yli pieni, tunnettu valikoima. Toisin vertailun pohjalta lajitellut kuten Quicksort tai Mergesort, jotka luottavat parilliselta elementti vertailut, Counting Sort määrittää lajitellun järjestyksen laskemalla taajuus kunkin erillisen arvon. Tämä lähestymistapa tuottaa lineaarisen ajan monimutkaisuus suotuisissa olosuhteissa, joten se go-to valinta monia suorituskykyä kriittisiä sovelluksia, joissa syöte domain on rajoitettu.

Algoritmi oli ensimmäinen kuvattu Harold H. Seward vuonna 1954 ja pysyy perustavan tekniikan tietojenkäsittelytieteessä. Sen yksinkertaisuus ja tehokkuus tekevät siitä ihanteellisen tehtäviin kuten lajittelu opiskelija-iät, arvosanat, tai minkä tahansa kokonaisluku tiedot vaatimaton hajota. Kun vivuttamalla apuvaraston suhteessa arvo-alue, Counting Sort välttää O(n log n) alempi raja vertailu lajittelu, saavuttaa O(n + k) aika, jossa k on valikoima syöttöarvot.

Miten lasken Lajitelma toimii

Core mekanismi Counting Sort on yksinkertainen: se laskee, kuinka monta kertaa jokainen arvo näkyy syöttöjärjestelmä, sitten käyttää, että lasketaan kunkin elementin lopullinen asema. Prosessi koostuu kolmesta erillisestä vaiheesta:

  1. Koostumus:[] Luo kokoluokka k (tuloarvojen vaihteluväli), alusta nollaksi. Iteroidaan sisääntulomatriisin läpi ja lisätään kunkin arvon lukumäärää.
  2. Kirjoitan etuliitteet:[ Muuntaa laskentamatriisin prefix-sum-matriisiksi, jossa jokainen indeksin i elementti pitää kumulatiivisen määrän elementeistä, jotka ovat pienempiä tai yhtä suuria kuin i. Tämä vaihe määrittää lähtöasennot kullekin lajitellun tulosteen erilliselle arvolle.
  3. Pelaavat elementit:[ Kävele sisääntuloaukon oikealta vasemmalle (vakavuudelle), käytä laskentaa löytääksesi oikean indeksin lähtömatriisista, aseta elementti sinne ja poista kreivi. Lopullinen tuloste on lajiteltu kopio syötteestä.

Algoritmi palauttaa uuden lajitellun arrayn, jolloin alkuperäinen ei muutu. Muoto nimeltä place Counting Sort[] on olemassa, mutta sitä käytetään harvoin, koska se vaarantaa joko vakauden tai tilan tehokkuuden.

Vaiheittainen esimerkki

Harkitkaa lajittelemista [4, 2, 2, 8, 3, 3, 1][, jossa arvot vaihtelevat 0-8.

  1. Korkeus: Lukujonon koko 9 (0...8) → [[0,1,1,2,1,1,00,00,1]. (Indeksi 1 ilmestyy kerran, indeksi 2 kahdesti, indeksi 3 kaksi kertaa, indeksi 4 kerran, indeksi 8 kerran.)
  2. Edeltävä summa:[ Muunna kumulatiiviseksi → [0,1,3,5,6,6,6,6,7]. Nyt jokainen arvo kertoo meille lähtöpaikan kyseisen numeron lajitellussa tuotoksessa.
  3. Output:[ Traverse original array from end: first element read is 1 → position = count[1] - 1 = 0 → output[0] =, decrement count[1] to 0. Seuraava on 3 → positio = count[3] - 1 = 4 → output[4]=3, count[3]=4. Jatka kunnes kaikki elementit on asetettu. Lopullinen tulos: [1,2,2,3,3,4,8].

Tämä esimerkki osoittaa, miten Counting Sot välttää vertailut kokonaan, tukeutuen yksinomaan aritmeettinen toiminta.

Laskemisen monimutkaisuus

Aikakompleksisuus

  • Paras, keskimmäinen ja pahin tapaus:[ O(n + k), jossa n on elementtien lukumäärä ja k on syöttöarvojen vaihteluväli. Kun k on pieni suhteessa n, algoritmi kulkee lineaarisessa ajassa.
  • Vertailun lajiin:[ Quicksortilla ja Mergesortilla on O(n log n) keskimääräinen monimutkaisuus. N = 106 ja k = 1000, Counting Sort (... 1 001 000 operaatiota) on noin 13 kertaa nopeampi kuin tyypillinen O(n log n) laji.

Space Complexity

  • Erityinen:[ O(k) lähtömatriisille. Tämä muistin yläpuolella voi olla kohtuuton, jos k on suuri (esim. 32-bittisten kokonaislukujen lajittelu, jossa k = 232).
  • Tavanomainen muunnos:[ vaatii n-kokoisen lisälähtösarjan; in-place -versiot uhraavat stabiiliuden tai käyttävät monimutkaista indeksimanipulointia.

Milloin käytetään laskentaa

Culling Sort on tehokkain seuraavissa olosuhteissa:

  • Syöttö koostuu kokonaislukuja (tai tietoja, jotka voidaan kartoittaa pieni kokonaislukualue, kuten merkkejä tai erillisiä luokkia).
  • Vaihteluväli k ei ole merkittävästi suurempi kuin n. Yhteinen nyrkkisääntö on k ≤ O(n).
  • Muistia ei ole ankarasti rajoitettu, koska laskenta- ja lähtöpuskuri vaatii lisätilaa.
  • Vakautta tarvitaan (esim. lajittelu useilla avaimilla). Vakiototeutus on vakaa, kun elementtejä sijoitetaan oikealta vasemmalle.

Erinomainen käyttötapa koskee lajitteluluokkia (0..100), ikäluokkia (0...120), tuoteluokkia (jopa muutama sataa tuoteyksikköä) tai aliohjelmaa [[...]Radix-lajitelmassa[[...]].

Rajoitukset ja huomiot

Nopeudestaan huolimatta Counting Sortilla on haittapuolia, jotka rajoittavat sen sovellettavuutta:

  • Vain osa:[] Se ei voi suoraan lajitella liukulukuja tai -jonoja, ellei niitä muunneta yhteenliittyväksi kokonaislukuksi.
  • Suuren alueen:[ Jos k kääpiöitä n... esimerkiksi 100 numeroa, joiden arvot ovat 1-107...
  • Ei-mukautuva:[ Counting Sort edellyttää aina koko syötteen skannausta ja laskentamatriisin rakentamista, vaikka tiedot olisivat jo lajiteltuja tai lähes lajiteltuja.
  • Negatiiviset arvot:[ Standard Counting Sort olettaa ei-negatiivisia kokonaislukuja. Negatiivisten tietojen käsittelemiseksi voit siirtää arvoja vähentämällä minimin (mitat 0:sta max:iin . . min).

Nämä rajoitukset tarkoittavat Counting Sort on erikoistunut työkalu, ei universaali korvaa yleiskäyttöisiä algoritmeja.

Vertailu lajitteleviin algoritmeihin

Lasketaan lajitelma vs. Radix Järjestä

Radix Järjestä laajentaa ideaa lajittelun numeroita vähiten merkittävä kaikkein merkittävin, käyttäen vakaa laji (usein Counting Sort) kullakin numerolla. Vaikka Counting Sort toimii yhdellä syötöllä yli koko alueen k, Radix Sort suorittaa useita kulkee yli pienempi numeroväli (esim., base 256), vähentää muistin käyttöä suuri k. Esimerkiksi lajittelu 32-bittinen kokonaislukuja Counting Sort edellyttäisi lukusarja 232 merkinnät, kun taas Radix Järjestä 8-bittinen numerot vaativat 256 merkinnät per pass ja vain neljä syöttöä.

Lasketaan lajittele vs. Ämpäri Järjestä

Bucket Järjestä jakaa elementtejä useita kauhoja ja lajittelee kunkin kauhan erikseen (usein lisäämällä laji). Counting Sort voidaan nähdä erityistapauksena Bucket Järjestä, jossa jokainen kauha vastaa yksi erillinen arvo. Bucket Järjestä toimii hyvin tasaisesti jaettu kelluva piste tietoja, mutta Counting Sort on rajoitettu kokonaisluku verkkotunnuksia.

Vakaan laskentajärjestelmän toteuttaminen

Vakaus on tärkeää, kun lajittelu yhdellä avaimella samalla säilyttää suhteellisen järjestyksen tasa-arvoisten osien toisesta avaimesta. Standard Counting Sort -algoritmi on luonnostaan vakaa, kun lähtösijoitussilmukka kulkee syötteen oikealta vasemmalle. Tässä on tekstillinen ääriviiva vakaalle versiolle:

  1. Laske laskentataulukko kuvatulla tavalla.
  2. Muunna etuliitteen summiksi (sijoitukset kunkin arvon lajiteltu tuloste).
  3. Iteroidaan syötejärjestelmä käänteisessä järjestyksessä. Kunkin elementin osalta se asetetaan sen arvon osoittamaan asentoon, sitten decrement, joka lasketaan.

Koska käsittelemme elementtejä lopusta, tietyn arvon viimeinen esiintyminen menee korkeimpaan mahdolliseen indeksiin, säilyttäen suhteellisen järjestyksen. Tämä vakaa versio on välttämätön Radix Järjestä toimimaan oikein jokaisella numerolla.

Käytännön sovellukset

  • Koulutusjärjestelmät:[ Lajittelemalla satoja koetuloksia (vaihteluväli 0..100) O(n) ajassa.
  • Bioinformatiikka:[ Lajittelulukumäärät tai DNA-k-mer-taajuudet, kun aakkoskoko on pieni (A, C, G, T).
  • Tietokannan indeksin ylläpito:[ Lajittelemalla yksilöllisiä kokonaislukutunnisteita riittävän pieniksi, jotta ne sopivat muistiin.
  • Kuvan käsittely:[ Histogrammiastian tai väri-intensiteetin lajittelu (0...255) rakenteilla olevien hakupöytäen yhteydessä.
  • Lajittelu toissijaisen avaimen mukaan:[ Käytetty Radix Sortissa, joka on työhevonen tehokkaaseen lajitteluun monilla kirjastoilla ja kielillä (esim. .NET-ajoaika käyttää mukautuvaa algoritmien yhdistelmää, mukaan lukien Counting Sort for small ranges).

Lisätietoja teoriasta ja muunnelmista saat arvovaltaisilta referensseiltä, kuten Wikipedia: Counting Sort] ja [] Geeksfor Geeks: Counting Sort[]. Käytännön vertailuja muihin algoritmeihin on []]Brilliant.

Optimoidaan laskentaa suurille etäisyyksille

Kun k on suuri, mutta n on myös suuri, puhdas Counting Sort tulee muisti-intensiivinen. Useita optimointia on olemassa:

  • Kaavittu harvalukuisuus:[ Käytä hash-karttaa vierekkäisen ryhmän sijaan, kun käytettyjen arvojen vaihteluväli on suuri, mutta erillisten arvojen määrä on pieni. Tämä toimii vakioaikaindeksinä ylimenon vuoksi, mutta vähentää muistin kulutusta.
  • Hybridien lähestymistavat:[ Yhdistä Lasku Lajittele muiden algoritmeja. Esimerkiksi, jos vaihteluväli ylittää 106, käytä Radix Järjestä pohja, joka pitää numerot pieninä.
  • Paikalla olevat vaihtoehdot:[ Jotkut optimointit vähentävät lisätilaa O(k) ilman lähtömatriisia, mutta yleensä ne uhraavat vakautta tai vaativat sykliä paikantaa paikkoja.

Päätelmät

Counting Sort erottuu huomattavan tehokkaana algoritmina kokonaislukujen lajitteluun, kun arvoalue on pieni suhteessa alkuaineiden määrään. Sen O(n + k) aikakompleksisuus ja lineaarinen suorituskyky tekevät siitä välttämättömän skenaarioissa kuten laatulajittelussa, Radix Järjestä aliohjelmat ja sovellukset, joissa on rajoitettu kokonaislukuavaimet. Algoritmi. riippuvuuden kokonaislukusyötteestä ja sen muistin yläpuolella suurille ajoneuvoille muistuttavat meitä siitä, että mikään yksittäinen laji ei ole optimaalinen kaikissa tilanteissa. Ymmärtämällä kun Counting Sort Excels.Ja kun se epäonnistuu....