Lisäyslajittelualgoritmi sisään Java Ohjelmaesimerkin kanssa

⚡ Älykäs yhteenveto

Lisäyslajittelu Java rakentaa taulukon lajitellun osan yksi alkio kerrallaan siirtäen suurempia arvoja oikealle, kunnes jokainen avain on oikeassa paikassa, mikä tekee siitä ihanteellisen pienille tietojoukoille.

  • 🔘 Määritelmä: Lisäyslajittelu poistaa yhden elementin ja lisää sen oikeaan paikkaan lajitellun osan sisällä.
  • ☑️ Prosessi: Jokainen läpimenokerta vertaa avainta aikaisempiin arvoihin ja siirtää suurempia arvoja yhden pykälän oikealle.
  • Ohjelmoida: Java esimerkki lajittelee luvut {860, 8, 200, 9} ja tulostaa jokaisen vertailun ja vaihdon.
  • 🧪 Monimutkaisuus: Paras tapaus suoritetaan ajassa O(n), kun taas keskimääräinen ja huonoin tapaus saavuttavat ajan O(n²).
  • 🛠️ Muisti: Lajittelu tapahtuu paikallaan, joten aputila pysyy arvossa O(1) minkä tahansa kokoisella taulukolla.
  • 📊 Käyttäytyminen: Algoritmi on vakaa ja mukautuva, joten lähes lajitellut taulukot valmistuvat hyvin vähällä siirrolla.

Lisäyslajittelualgoritmi sisään Java

Mikä on lisäyslajittelualgoritmi?

Lisäyslajittelu on yksinkertainen lajittelualgoritmi, joka sopii pienille tietojoukoille. Jokaisen iteraation aikana algoritmi:

  • Poistaa elementin taulukosta.
  • Vertaa sitä alueen suurimpaan arvoon ryhmä.
  • Siirtää elementin oikeaan paikkaan.

Toiminta peilaa tapaa, jolla kortinpelaaja järjestää käden: jokainen uusi kortti nostetaan ja työnnetään vasemmalle jokaisen suuremman kortin ohi, kunnes se on oikeassa paikassa. Koska kaikki siirtäminen tapahtuu alkuperäisen taulukon sisällä, lisäyslajittelu on sekä paikallaan oleva että vakaa.

Se kuuluu samaan aloittelijaystävällisten tuotteiden perheeseen. Java lajittelurutiinit kuten kupla, mutta se suorittaa yleensä paljon vähemmän kirjoituksia datalle, joka on jo osittain järjestetty.

Lisäyslajittelualgoritmiprosessi

Tässä on, kuinka lisäyslajittelualgoritmiprosessi toimii graafisesti:

Animoidut traclisäyslajittelualgoritmin e järjestämällä lajittelemattoman listan uudelleen
Lisäyslajittelualgoritmiprosessi

Animaatio toistaa samat kolme vaihetta Java alla oleva ohjelma suorittaa. Koeajopöytä tracSuorittaa nuo vaiheet esimerkkitaulukossa {860, 8, 200, 9} täsmälleen sellaisena kuin ohjelma tulostaa ne suorituksen aikana.

Siirtää Avainelementti Tehdyt vertailut Taulukko syötön jälkeen
1 8 8 vastaan ​​860 8 860 200 9
2 200 200 vastaan ​​860 8 200 860 9
3 9 9 vastaan ​​860, sitten 9 vastaan ​​200 8 9 200 860

Huomaa, että kolmannessa vaiheessa tarvitaan kaksi vertailua, koska avaimen 9 on kuljettava kahden suuremman arvon ohi. Vertailujen määrä siis kasvaa sen mukaan, kuinka kaukana epäjärjestyksessä kukin elementti alkaa.

Java Ohjelmaesimerkki taulukon lajitteluun lisäyslajittelualgoritmin avulla:

Alla oleva ohjelma lajittelee taulukon {860, 8, 200, 9} ja tulostaa juoksevan kommentin, joten jokainen vertailu ja jokainen siirto on näkyvissä. Tallenna se nimellä InsertionSortExample.java ja käännä se millä tahansa JDK 8:lla tai uudemmalla versiolla.

package com.guru99;
 
public class InsertionSortExample {
 
	
    public static void main(String a[])
    {    
        int[] myArray  = {860,8,200,9};  
        
        System.out.println("Before Insertion Sort");  
        
        printArray(myArray);
            
        insertionSort(myArray);//sorting array using insertion sort    
           
        System.out.println("After Insertion Sort");  
        
        printArray(myArray);   
    }    
 public static void insertionSort(int arr[]) 
	{  
        int n = arr.length;  
        
        for (int i = 1; i < n; i++)
        {   System.out.println("Sort Pass Number "+(i));
            int key = arr[i];  
            int j = i-1;  
            
            while ( (j > -1) && ( arr [j] > key ) ) 
            {  
            System.out.println("Comparing "+ key  + " and " + arr [j]); 
                arr [j+1] = arr [j];  
                j--;  
            }  
            arr[j+1] = key; 
            System.out.println("Swapping Elements: New Array After Swap");
            printArray(arr);
        }  
    }
 static void printArray(int[] array){
	    
	    for(int i=0; i < array.length; i++)
		{  
			System.out.print(array[i] + " ");  
		} 
	    System.out.println();
	    
	}
}

Kurssin suorittaminen tuottaa trace näkyy tässä. Jokainen Lajittelupassin numero rivi merkitsee ulomman silmukan yhtä iteraatiota, ja jokaisen vaihdon jälkeen tulostettava rivi näyttää taulukon sellaisena kuin se on sillä hetkellä.

Code lähtö:

Before Insertion Sort
860 8 200 9 
Sort Pass Number 1
Comparing 8 and 860
Swapping Elements: New Array After Swap
8 860 200 9 
Sort Pass Number 2
Comparing 200 and 860
Swapping Elements: New Array After Swap
8 200 860 9 
Sort Pass Number 3
Comparing 9 and 860
Comparing 9 and 200
Swapping Elements: New Array After Swap
8 9 200 860 
After Insertion Sort
8 9 200 860

Lisäyslajittelun aika- ja paikkakompleksisuus

Lisäyslajittelun suorituskyky riippuu suuresti syötteen jo valmiiksi järjestäytyneestä arvosta, minkä vuoksi paras ja huonoin tapaus eroavat toisistaan ​​kokonaisen kasvukertaluvun verran.

tapaus Syöttöehto Ajan monimutkaisuus
Parhaat Taulukko on jo lajiteltu, joten sisempi while-silmukka ei koskaan toimi. O (n)
Keskimäärin Elementit saapuvat satunnaisessa järjestyksessä O(n²)
pahin Taulukko lajitellaan käänteisesti, joten jokainen näppäin siirtyy eteenpäin O(n²)

Tilankäyttö on paljon yksinkertaisempaa. Vain tiskipöydät i, j, n ja key luodaan ja taulukko järjestetään uudelleen paikalleen, joten aputila on O(1) riippumatta siitä, kuinka suureksi syöte kasvaa.

Koska sisempi silmukka pysähtyy heti, kun se saavuttaa pienemmän arvon, lisäyslajittelua kuvataan adaptiiviseksi: mitä lähempänä syöte on lajiteltua järjestystä, sitä lähemmäksi suoritusaika liikkuu lineaarista.

Lisäyslajittelun edut ja haitat

Lisäyslajittelu säilyy tuotantokirjastoissa neliöllisen keskiarvon tapauksestaan ​​huolimatta, koska sen vakiotekijät ovat pieniä ja sen käyttäytyminen on ennustettavaa.

edut

  • Helppo kirjoittaa ja helppo trackäsin, mikä sopii sekä opetukseen että haastatteluihin.
  • Vakaa, joten saman avaimen jakavien tietueiden alkuperäinen järjestys säilyy.
  • Paikallaan, tarvitsee vain O(1) lisämuistia syöttötaulukon lisäksi.
  • Adaptiivinen, saavuttaa O(n):n datassa, joka on jo lähes lajiteltu.
  • Verkossa, mikä tarkoittaa, että se voi lajitella listaa jo uusien elementtien saapuessa.

Haitat

  • Satunnaisen tai käänteisessä järjestyksessä olevan syötteen neliöllinen aika tekee siitä sopimattoman suurille taulukoille.
  • Jokainen shift kirjoittaa taulukkoon, joten se siirtää enemmän dataa kuin valintalajittelu.
  • Yhdistämislajittelu ja pikalajittelu suoriutuvat siitä selvästi paremmin, kun syöte läpäisee muutaman kymmenen elementin.

Käytännöllinen sääntö on turvautua lisäyslajitteluun, kun taulukko on pieni, kun tiedot ovat lähes järjestyksessä tai kun hajoita ja hallitse -lajittelu on supistanut osion muutamaan alkioon.

Lisäyslajittelu vs. Bubble-lajittelu vs. valintalajittelu

Kaikki kolme algoritmia ovat toisen asteen vertailulajitteluja, mutta ne eroavat toisistaan ​​vakauden, järjestettyyn syötteeseen reagoinnin ja suorittamiensa kirjoituskertojen määrän suhteen.

Kriteeri Lisäyslajittelu Bubble Lajittele Valinta Lajittele
Paras tapaus O (n) O(n) varhaisen poistumisen lipulla O(n²)
Keskimääräinen ja pahin tapaus O(n²) O(n²) O(n²)
Lisätilaa O (1) O (1) O (1)
Vakaa Kyllä Kyllä Ei, vakiomatriisiversiossa
Mukautuva Kyllä Kyllä, kun käytetään lippuoptimointia Ei
Kirjoittaa taulukkoon Paljon muutoksia, vähän järjestetyssä datassa Monet vaihdot Täsmälleen n-1 vaihtoa

Valintalajittelu voittaa, kun kirjoitus on kallista, koska se suorittaa vähiten vaihtoja. Lisäyslajittelu voittaa lähes kaikkialla muualla tässä mittakaavassa, erityisesti osittain järjestetyssä datassa, minkä vuoksi kirjastolajittelut, kuten takana oleva yhteinen Java harjoitukset ja JDK:n sisäiset osat siirtyvät siihen hyvin pienille osioille.

UKK

Jo ensimmäinen alkio on jo lajiteltu, yhden pituinen alitaulukko. Indeksistä 1 aloittaminen tarkoittaa, että silmukalla on aina jotain, mihin verrata, joten i-kohdan avain lisätään sen vasemmalla puolella olevaan järjestettyyn lohkoon.

Tekoälyavustajat voivat lukea harjoitustehtävän rivi riviltä, ​​luoda ylimääräisiä testitaulukoita ja arvioida Big O:n kasvua lähdekoodista. Käsittele selitystä opiskeluapuna ja vahvista monimutkaisuusväitteet oppikirjaa vasten ennen niiden lainaamista.

Kyllä. GitHub Copilot suorittaa normaalin lisäyslajittelun metodin allekirjoituksen tai kommentin perusteella. RevTarkista reunaehdot itse, koska luodut silmukat käyttävät joskus j >= 0 tai j > -1 -arvoa ristiriidassa ympäröivän koodin kanssa.

Binäärilisäyslajittelu paikantaa lisäyskohdan binäärihaulla lineaarisen skannauksen sijaan, leikkaamalla vertailut elementtikohtaisesti välillä O(n): - <log n>. Siirtyvä työ pysyy muuttumattomana, joten kokonaisaikakompleksisuus pysyy arvossa O(n²).

Kyllä. Rekursiivinen versio lajittelee ensimmäiset n-1 elementtiä ja lisää sitten viimeisen elementin tähän lajiteltuun etuliitteeseen. Se vastaa iteratiivista aikakompleksisuutta, mutta lisää O(n) pinotilaa, joten silmukkaversio on käytännössä parempi.

Osittain. Primitiivisille osioille käytetty kaksoispikalajittelu palaa lisäyslajitteluun hyvin pienillä osioilla, ja objekteille käytetty TimSort lajittelee lyhyet sarjat binäärisellä lisäyslajittelulla ennen niiden yhdistämistä.

Yleisiä virheitä ovat ulomman silmukan aloittaminen kohdasta 0, arr[j] = key -merkinnän kirjoittaminen arr[j+1] = key -merkinnän sijaan ja j > -1 -vartijan poisjättäminen, joka heittää ArrayIndexOutOfBoundsException-poikkeuksen, kun avain kuuluu paikkaan nolla.

Kyllä. Korvaa suurempi kuin -testi compareTo-testillä, jos kyseessä on Comparable-tyyppi, tai Comparator-kutsulla. Siirto-logiikka pysyy muuttumattomana ja vakaus säilyy, millä on merkitystä, kun objekteilla on sama lajitteluavain.

Tiivistä tämä viesti seuraavasti: