Insertion Sort Algoritme i Java med programeksempel

⚡ Smart opsummering

Indsættelsessortering i Java opbygger en sorteret sektion af et array ét element ad gangen og flytter større værdier til højre, indtil hver nøgle lander på sin korrekte position, hvilket gør den ideel til små datasæt.

  • 🔘 Definition: Indsættelsessortering fjerner ét element og indsætter det på dets korrekte plads i den sorterede del.
  • ☑️ Proces: Hver gennemgang sammenligner nøglen med tidligere værdier og flytter større værdier én position til højre.
  • Program: Java eksempel sorterer {860, 8, 200, 9} og udskriver hver sammenligning og swap.
  • 🧪 kompleksitet: Det bedste tilfælde kører i O(n) tid, mens gennemsnitlige og værste tilfælde når O(n²).
  • 🛠️ Hukommelse: Sortering sker på stedet, så hjælperummet forbliver ved O(1) for enhver arraystørrelse.
  • 📊 Opførsel: Algoritmen er stabil og adaptiv, så næsten sorterede arrays afsluttes efter meget få forskydninger.

Insertion Sort Algoritme i Java

Hvad er Insertion Sort Algorithm?

Indsættelsessortering er en simpel sorteringsalgoritme, der er velegnet til små datasæt. Under hver iteration vil algoritmen:

  • Fjerner et element fra et array.
  • Sammenligner det med den største værdi i matrix.
  • Flytter elementet til dets korrekte placering.

Opførslen afspejler den måde, en kortspiller arrangerer en hånd på: hvert nyt kort tages op og skubbes til venstre forbi hvert større kort, indtil det hviler på det rigtige sted. Fordi al forskydning sker inden for det oprindelige array, er indsættelsessortering både på plads og stabil.

Den tilhører den samme familie af begyndervenlige Java sorteringsrutiner som boble sortering, men den udfører normalt langt færre skrivninger på data, der allerede er delvist ordnet.

Insertion Sort Algoritme Process

Her er hvordan indsættelsessorteringsalgoritmen fungerer grafisk:

Animeret trace af indsættelsessorteringsalgoritmen, der omorganiserer en usorteret liste
Insertion Sort Algoritme Process

Animationen gentager de samme tre trin Java Programmet nedenfor udføres. Tørløbstabellen tracUdfører disse trin på eksempelarrayet {860, 8, 200, 9}, præcis som programmet udskriver dem under kørsel.

Pass Nøgleelement Sammenligninger foretaget Opstilling efter passet
1 8 8 mod 860 8 860 200 9
2 200 200 mod 860 8 200 860 9
3 9 9 mod 860, derefter 9 mod 200 8 9 200 860

Bemærk at gennemgang 3 kræver to sammenligninger, fordi tast 9 skal passere to større værdier. Antallet af sammenligninger vokser derfor med hvor langt ude af rækkefølge hvert element starter.

Java Programeksempel til at sortere et array ved hjælp af Insertion Sort Algorithm:

Programmet nedenfor sorterer arrayet {860, 8, 200, 9} og udskriver en løbende kommentar, så hver sammenligning og hvert skift er synligt. Gem det som InsertionSortExample.java og kompilere den med en hvilken som helst JDK 8 eller nyere version.

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

At afholde klassen producerer tracvist her. Hver Sorteringspasnummer Linjen markerer én iteration af det ydre loop, og linjen, der udskrives efter hver swap, viser arrayet, som det ser ud på det tidspunkt.

Code Output:

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

Tids- og rumkompleksitet af indsættelsessortering

Indsættelsessorteringsydeevnen afhænger i høj grad af, hvor ordnet inputtet allerede er, hvilket er grunden til, at det bedste og det værste tilfælde adskiller sig med en hel vækstorden.

Kasse Inputbetingelse Tidskompleksitet
Bedre Arrayet er allerede sorteret, så den indre while-løkke kører aldrig O (n)
Gennemsnit Elementerne ankommer i tilfældig rækkefølge O(n²)
Værst Arrayet er sorteret i omvendt rækkefølge, så hver tast bevæger sig fremad O(n²)

Pladsudnyttelsen er langt enklere. Kun tællerne i, j, n og key oprettes, og arrayet omarrangeres på plads, så hjælperummet er O(1) uanset hvor stort inputtet vokser.

Fordi den indre løkke stopper, så snart den møder en mindre værdi, beskrives indsættelsessortering som adaptiv: jo tættere inputtet er på den sorterede rækkefølge, desto tættere bevæger køretiden sig mod lineær.

Fordele og ulemper ved indsættelsessortering

Indsættelsessortering overlever i produktionsbiblioteker på trods af sit kvadratiske gennemsnitstilfælde, fordi dens konstante faktorer er små, og dens adfærd er forudsigelig.

Fordele

  • Enkel at skrive og nem at trace i hånden, hvilket er velegnet til undervisning og interviews.
  • Stabil, så poster, der deler en nøgle, beholder deres oprindelige relative rækkefølge.
  • In-place, kræver kun O(1) ekstra hukommelse ud over input-arrayet.
  • Adaptiv, når O(n) på data, der allerede er næsten sorteret.
  • Online, hvilket betyder, at den kan sortere en liste, mens nye elementer stadig ankommer.

Ulemper

  • Kvadratisk tid på tilfældigt eller omvendt ordnet input gør den uegnet til store arrays.
  • Hvert skift skriver til arrayet, så det flytter flere data end sorteringsfunktion.
  • Merge sort og quicksort klarer sig bedre end det, når inputtet passerer et par dusin elementer.

En praktisk regel er at bruge indsættelsessortering, når arrayet er lille, når dataene næsten er i orden, eller når en divider-og-hersk-sortering har reduceret en partition til en håndfuld elementer.

Indsættelsessortering vs. Bubble-sortering vs. valgsortering

Alle tre algoritmer er kvadratiske sammenligningstyper, men de adskiller sig i stabilitet, i hvordan de reagerer på ordnet input, og i antallet af skrivninger, de udfører.

Kriterier Indsats sortering Bubble Sortere Valg af sortering
Bedste sag O (n) O(n) med et flag for tidlig exit O(n²)
Gennemsnit og værst tænkelige tilfælde O(n²) O(n²) O(n²)
Ekstra plads O (1) O (1) O (1)
Stabil Ja Ja Nej, i standard array-versionen
Adaptive Ja Ja, når flagoptimering bruges Ingen
Skriver til arrayet Mange skift, få på bestilte data Mange bytter Præcis n-1 swaps

Udvælgelsessortering vinder, når en skrivning er dyr, fordi den udfører færrest swaps. Indsættelsessortering vinder næsten alle andre steder på denne skala, især på delvist ordnede data, hvilket er grunden til bibliotekssorteringer som den bagved. fælles Java øvelser og JDK's interne komponenter skifter til det for meget små partitioner.

Ofte Stillede Spørgsmål

Det første element alene er allerede et sorteret underarray med længden én. At starte ved indeks 1 betyder, at løkken altid har noget at sammenligne med, så nøglen på position i indsættes i den ordnede blok til venstre for den.

AI-assistenter kan fortælle en testsekvens linje for linje, generere ekstra testarrays og estimere Big O-vækst ud fra kildekoden. Betragt forklaringen som et studiehjælpemiddel, og bekræft påstandene om kompleksitet i forhold til en lærebog, før du citerer dem.

Ja. GitHub Copilot fuldfører en standard indsættelsessortering fra en metodesignatur eller kommentar. RevSe selv randbetingelserne, fordi genererede løkker nogle gange bruger j >= 0 eller j > -1 i uoverensstemmelse med den omgivende kode.

Binær indsættelsessortering lokaliserer indsættelsespunktet med en binær søgning i stedet for en lineær scanning, hvor sammenligninger pr. element skæres fra O(n) til O(log n). Forskydningsarbejdet er uændret, så den samlede tidskompleksitet forbliver O(n²).

Ja. En rekursiv version sorterer de første n-1 elementer og indsætter derefter det sidste element i det sorterede præfiks. Den matcher den iterative tidskompleksitet, men tilføjer O(n) stakplads, så loop-versionen foretrækkes i praksis.

Delvist. Den dobbelte pivot-quicksortering, der bruges til primitiver, falder tilbage til en indsættelsessortering på meget små partitioner, og TimSort, der bruges til objekter, sorterer korte kørsler med binær indsættelsessortering, før den fletter dem.

De hyppigste fejl er at starte den ydre løkke ved 0, skrive arr[j] = key i stedet for arr[j+1] = key, og udelade j > -1 guarden, hvilket udløser ArrayIndexOutOfBoundsException, når nøglen hører hjemme på position nul.

Ja. Erstat større-end-testen med compareTo for en Comparable-type, eller med et Comparator-kald. Skiftlogikken er uændret, og stabiliteten bevares, hvilket er vigtigt, når objekter deler den samme sorteringsnøgle.

Opsummer dette indlæg med: