Beszúrási rendezési algoritmus Java programpéldával

⚡ Okos összefoglaló

Beszúrás szerinti rendezés Java egy tömb rendezett részét építi fel elemenként, a nagyobb értékeket jobbra tolva, amíg minden kulcs a megfelelő pozícióba nem kerül, így ideális kis adathalmazokhoz.

  • 🔘 Meghatározás: A beszúrásos rendezés eltávolít egy elemet, és beilleszti azt a rendezett rész megfelelő helyére.
  • ☑️ Folyamat: Minden menet összehasonlítja a kulcsot a korábbi értékekkel, és a nagyobbakat egy pozícióval jobbra tolja.
  • program: Az Java A példa rendezi a {860, 8, 200, 9} értékeket, és kinyomtatja az összes összehasonlítást és cserét.
  • 🧪 Bonyolultság: A legjobb eset O(n) idő alatt fut le, míg az átlagos és a legrosszabb eset eléri az O(n²) időt.
  • 🇧🇷 memória: A rendezés helyben történik, így a segédterület O(1) marad bármilyen tömbméret esetén.
  • 📊 Viselkedés: Az algoritmus stabil és adaptív, így a közel rendezett tömbök nagyon kevés eltolódás után befejeződnek.

Beszúrási rendezési algoritmus Java

Mi az a beszúrási rendezési algoritmus?

A beszúrásos rendezés egy egyszerű rendezési algoritmus, amely kis adatkészletekhez alkalmas. Minden iteráció során az algoritmus:

  • Eltávolít egy elemet a tömbből.
  • Összehasonlítja a legnagyobb értékkel a sor.
  • Az elemet a megfelelő helyre mozgatja.

A viselkedés tükrözi azt, ahogyan egy kártyajátékos elrendezi a lapjait: minden új lapot felvesz, és balra eltolja minden nagyobb kártya mellett, amíg a megfelelő helyre nem kerül. Mivel minden eltolódás az eredeti tömbön belül történik, a beszúrásos rendezés a helyén van és stabil is.

Ugyanabba a kezdőbarát családba tartozik. Java rendezési rutinok, mint buborékfajta, mégis általában sokkal kevesebb írást hajt végre a már részben rendezett adatokon.

Beillesztési rendezési algoritmus folyamata

A Beszúrás rendezési algoritmusa grafikusan a következőképpen működik:

eleven traca beszúrásos rendezési algoritmus e-je, amely egy rendezetlen listát rendez át
Beillesztési rendezési algoritmus folyamata

Az animáció ugyanazt a három lépést ismétli Java az alábbi program végrehajtja. A próbafuttatási táblázat tracVégezze el ezeket a lépéseket a {860, 8, 200, 9} minta tömbön, pontosan úgy, ahogy a program futásidőben kinyomtatja azokat.

Átmegy Kulcsfontosságú elem Összehasonlítások Tömb a passz után
1 8 8 az 860 ellen 8 860 200 9
2 200 200 az 860 ellen 8 200 860 9
3 9 9 a 860 ellen, majd 9 a 200 ellen 8 9 200 860

Figyeljük meg, hogy a 3. lépéshez két összehasonlítás szükséges, mivel a 9-es kulcsnak két nagyobb értéken kell áthaladnia. Az összehasonlítások száma tehát azzal növekszik, hogy az egyes elemek mennyire eltérnek a sorrendtől.

Java Programpélda egy tömb rendezésére beillesztési rendezési algoritmussal:

Az alábbi program rendezi a {860, 8, 200, 9} tömböt, és egy futó kommentárt nyomtat, így minden összehasonlítás és minden eltolás látható. Mentse el más néven InsertionSortExample.java és fordítsd le bármilyen JDK 8-as vagy újabb kiadással.

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

Az óra lebonyolítása eredményezi a tracitt látható. Mindegyik Rendezési szám A sor a külső ciklus egy iterációját jelöli, és az egyes swapok után kiírt sor a tömb aktuális állapotát mutatja.

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

A beszúrási rendezés időbeli és térbeli komplexitása

A beszúrásos rendezés teljesítménye nagymértékben függ attól, hogy mennyire rendezett a bemenet, ezért a legjobb és a legrosszabb eset egy egész növekedési renddel tér el egymástól.

Ügy Beviteli feltétel Az idő összetettsége
Legjobb A tömb már rendezett, így a belső while ciklus soha nem fut le. O (n)
Átlagos Az elemek véletlenszerű sorrendben érkeznek O(n²)
Legrosszabb A tömb fordított sorrendben van rendezve, így minden kulcs előre kerül O(n²)

A helykihasználás sokkal egyszerűbb. Csak a pultok i, j, n és a key létrejönnek, és a tömböt a helyén átrendezzük, így a segédterület O(1)-es, függetlenül attól, hogy mennyire nő a bemenet.

Mivel a belső ciklus leáll, amint eléri a kisebb értéket, a beszúrásos rendezést adaptívnak nevezzük: minél közelebb van a bemenet a rendezett sorrendhez, annál közelebb kerül a futási idő a lineárishoz.

A beszúrásos rendezés előnyei és hátrányai

A beszúrásos rendezés a kvadratikus átlag esete ellenére is fennmarad az éles könyvtárakban, mivel konstans tényezői aprók, viselkedése pedig kiszámítható.

Előnyök

  • Egyszerűen írható és könnyen elkészíthető trackézzel, ami alkalmas oktatásra és interjúkra.
  • Stabil, így az azonos kulcsot megosztó rekordok megtartják eredeti relatív sorrendjüket.
  • Helyben működik, a bemeneti tömbön túl csak O(1) extra memóriára van szükség.
  • Adaptív, O(n) értéket ér el olyan adatokon, amelyek már majdnem rendezettek.
  • Online, ami azt jelenti, hogy rendezni tudja a listákat, miközben az új elemek még érkeznek.

Hátrányok

  • A véletlenszerű vagy fordított sorrendű bemeneten alkalmazott kvadratikus idő miatt nem alkalmas nagy tömbökhöz.
  • Minden egyes eltolás a tömbbe ír, tehát több adatot mozgat, mint a kijelöléses rendezés.
  • Az összevont és a gyors rendezés kényelmesen felülmúlja ezt, ha a bemenet néhány tucat elemen halad át.

Egy gyakorlati szabály az, hogy beszúrós rendezést akkor használunk, ha a tömb kicsi, amikor az adatok majdnem rendezettek, vagy amikor az oszd meg és uralkodj rendezés a partíciót néhány elemre redukálta.

Beszúrásos rendezés vs. BubblRendezés vs. Kijelöléses rendezés

Mindhárom algoritmus kvadratikus összehasonlító rendezés, mégis különböznek stabilitásukban, abban, hogyan reagálnak a rendezett bemenetre, és az általuk végrehajtott írások számában.

Kritériumai Beszúrás rendezése Bubble Rendezés Válogatás rendezése
Legjobb eset O (n) O(n) korai kilépési jelzővel O(n²)
Átlagos és legrosszabb eset O(n²) O(n²) O(n²)
Extra hely O (1) O (1) O (1)
Stabil Igen Igen Nem, a standard tömbverzióban
Adaptív Igen Igen, ha a jelzőoptimalizálást használják Nem
Írás a tömbbe Sok eltolódás, kevés rendezett adatokon Sok csere Pontosan n-1 csere

A szelekciós rendezés akkor nyer, ha az írás költséges, mivel a legkevesebb cserét végzi. A beszúrásos rendezés szinte mindenhol máshol nyer ezen a skálán, különösen részben rendezett adatokon, ezért a könyvtári rendezések, mint például a mögötte lévő, a legjobbak. közös Java ünnepély és a JDK belső részei nagyon kis partíciók esetén erre váltanak.

GYIK

Már az első elem is egy rendezett, egy hosszúságú altömb. Az 1-es indextől való kezdés azt jelenti, hogy a ciklusnak mindig van mivel összehasonlítani, így az i-edik pozícióban lévő kulcs a tőle balra lévő rendezett blokkba kerül beillesztésre.

A mesterséges intelligencia asszisztensek sorról sorra felolvashatják a próbatételt, extra teszttömböket generálhatnak, és a forráskódból megbecsülhetik a Big O növekedését. A magyarázatot tanulmányi segédletként kezeljük, és a bonyolultságra vonatkozó állításokat egy tankönyvvel szemben ellenőrizzük, mielőtt idéznénk őket.

Igen. GitHub másodpilóta egy szabványos beszúrási rendezést hajt végre egy metódus aláírásából vagy megjegyzéséből. RevNézd meg a határfeltételeket magad, mert a generált ciklusok néha j >= 0 vagy j > -1 értéket használnak, ami inkonzisztens a környező kóddal.

A bináris beszúrásos rendezés lineáris keresés helyett bináris kereséssel határozza meg a beszúrási pontot, elemenként O(n)-től O(log n)-ig vágva az összehasonlításokat. Az eltolódási munka változatlan, így az összesített időbonyolultság O(n²) marad.

Igen. A rekurzív változat rendezi az első n-1 elemet, majd beszúrja az utolsó elemet a rendezett előtagba. Megfelel az iteratív időbonyolultságnak, de O(n) veremterületet ad hozzá, így a gyakorlatban a ciklusos változat az előnyösebb.

Részben. A primitívekhez használt kettős pivot gyorsrendezés nagyon kis partíciókon beszúrásos rendezésre tér vissza, az objektumokhoz használt TimSort pedig rövid futamokat rendez bináris beszúrásos rendezéssel, mielőtt összevonná őket.

A gyakori hibák a külső ciklus 0-val történő indítása, az arr[j] = key írása az arr[j+1] = key helyett, valamint a j > -1 Guard elhagyása, amely ArrayIndexOutOfBoundsException kivételt dob, amikor a kulcs a nulla pozícióban található.

Igen. Comparable típus esetén a „nagyobb, mint” tesztet cserélje le compareTo-ra, vagy Comparator hívással. Az eltolási logika változatlan marad, és a stabilitás megmarad, ami akkor fontos, ha az objektumok ugyanazt a rendezési kulcsot használják.

Foglald össze ezt a bejegyzést a következőképpen: