Výběr Třídění v Java Program s příkladem

⚡ Chytré shrnutí

Řazení výběru Java opakovaně prohledává netříděnou část pole, najde nejmenší zbývající hodnotu a prohodí ji na pozici, přičemž práci dokončí s maximálně n-1 výměnami bez ohledu na pořadí vstupu.

  • 🔘 Definice: Výběrové řazení rozděluje pole při každém průchodu na seřazenou a neseřazenou oblast.
  • ☑️ Process: Každý průchod prohledává netříděnou oblast a hledá nejnižší prvek a ten následně prohodí.
  • (Tj. Program: Jedno Java Příklad seřadí {860, 8, 200, 9} a vypíše každé porovnání a záměnu.
  • 🧪 Složitost: Nejlepší, průměrný a nejhorší případ probíhají v čase O(n²), protože počet porovnání se nikdy nezmenšuje.
  • 🛠️ Paměť: Výměny probíhají uvnitř původního pole, takže pomocný prostor zůstává na O(1).
  • 📊 Chování: Klasická verze je nestabilní, přesto provádí nejméně zápisů ze všech kvadratických typů.

Výběr Třídění v Java Program s příkladem

Jak funguje výběrové řazení?

Selection Sort implementuje jednoduchý algoritmus řazení takto:

  • Algoritmus opakovaně hledá nejnižší prvek.
  • Vyměňte aktuální prvek za prvek s nejnižší hodnotou
  • S každou iterací/průchodem druhu výběru se prvky vymění.

Každý průchod proto zpracovává řada jako dvě oblasti: seřazený blok, který roste zleva, a neseřazený blok, který se zmenšuje zprava. Algoritmus prochází neseřazený blok, pamatuje si index nejmenší hodnoty, kterou narazí, a tuto hodnotu vymění s první neseřazenou pozicí.

Protože v jednom průchodu dochází pouze k jedné výměně, pole n prvků je seřazeno po maximálně n-1 výměnách. Tato vlastnost odlišuje tuto rutinu od ostatních rutin pro začátečníky. Java třídicí algoritmy, které přesouvají data mnohem častěji.

Jedno tracNásledující text následuje za vzorovým polem {860, 8, 200, 9} přesně tak, jak ho program v následující části vytiskne za běhu.

Přejít Srovnání vytištěna Nejmenší nalezená hodnota Pole po swapu
Home - - 860 8 200 9
1 860 a 8, 8 a 200, 8 a 9 8 8 860 200 9
2 860 a 200, 200 a 9 9 8 9 200 860
3 200 a 860 200 8 9 200 860

Dva detaily v tom tracStojí za to se u nich zastavit. Zaprvé, i ve 3. průchodu se stále hlásí výměna, i když se pořadí nezmění, protože nejmenší zbývající hodnota se již nachází na aktuálním indexu a program si prvek vymění sám se sebou. Zadruhé, počet porovnání se v každém průchodu sníží o jedno (tři, pak dvě, pak jedna), což je vzorec, který odpovídá údajům o složitosti uvedeným dále na stránce.

Java Program pro implementaci třídění výběru

Níže uvedená třída se jmenuje SelectionSortAlgo a nachází se v balíčku com.guru99. Metoda main() deklaruje vzorové pole, vypíše ho, předá ho metodě selection() k seřazení a znovu ho vypíše. Pomocná metoda printArray() zapíše všechny prvky na jeden řádek, což vytvoří čitelný protokol pass-by-pass.

Uvnitř selection() vnější smyčka označuje hranici mezi seřazenými a neseřazenými oblastmi, proměnná index drží pozici nejmenší dosud viděné hodnoty a tři přiřazení na konci každého průchodu provádějí záměnu.

package com.guru99;
 
public class SelectionSortAlgo {
 
	public static void main(String a[])
	{  
		int[] myArray = {860,8,200,9}; 
		
		System.out.println("------Before Selection Sort-----");
 
		printArray(myArray);
 
 
		selection(myArray);//sorting array using selection sort  
 
		System.out.println("-----After Selection Sort-----");  
 
		printArray(myArray); 
	} 
	
		public static void selection(int[] array)
	{  
		for (int i = 0; i < array.length - 1; i++)  
		{  System.out.println("Sort Pass Number "+(i+1));
			int index = i;  
			for (int j = i + 1; j < array.length; j++)
			{   
			    System.out.println("Comparing "+ array[index]  + " and " + array[j]);  
				if (array[j] < array[index]){ 
				System.out.println(array[index]  + " is greater than " + array[j] );
					index = j;
				
				
				}  
			}  
 
			int smallerNumber = array[index];   
			array[index] = array[i];  
			array[i] = smallerNumber;  
			System.out.println("Swapping Elements: New Array After Swap");
			printArray(array);
		}  
	}  
	static void printArray(int[] array){
	    
	    for(int i=0; i < array.length; i++)
		{  
			System.out.print(array[i] + " ");  
		} 
	    System.out.println();
	    
	}
 
}

Výstup:

Kompilace a spuštění třídy vygeneruje níže uvedený protokol konzole s jedním blokem výstupu na průchod.

------Before Selection Sort-----
860 8 200 9 
Sort Pass Number 1
Comparing 860 and 8
860 is greater than 8
Comparing 8 and 200
Comparing 8 and 9
Swapping Elements: New Array After Swap
8 860 200 9 
Sort Pass Number 2
Comparing 860 and 200
860 is greater than 200
Comparing 200 and 9
200 is greater than 9
Swapping Elements: New Array After Swap
8 9 200 860 
Sort Pass Number 3
Comparing 200 and 860
Swapping Elements: New Array After Swap
8 9 200 860 
-----After Selection Sort-----
8 9 200 860

Začátečníky při prvním spuštění tohoto příkladu zaskočí dva problémy. Protože soubor deklaruje package com.guru99;, zdroj musí existovat v odpovídajícím com/guru99 adresář, jinak kompilátor hlásí neshodu názvů balíčků nebo tříd. Třída musí být pak spuštěna pod svým plně kvalifikovaným názvem, java com.guru99.SelectionSortAlgo, protože prostý java SelectionSortAlgo vyvolává NoClassDefFoundError.

Další častou pastí jsou hranice smyčky. Vnější smyčka končí v array.length - 1 a vnitřní smyčka začíná na i + 1; změna kterékoli z hranic vyvolá další prázdný průchod nebo výjimku ArrayIndexOutOfBoundsException.

Časová a prostorová složitost výběrového řazení

Vnitřní smyčka v programu vždy běží na konec pole, takže algoritmus provádí stejný počet porovnání bez ohledu na to, jak data vypadají. Pro pole o n prvcích je tento součet n(n-1)/2, což pro čtyřprvkový vzorek se rovná šesti, a výstup výše skutečně vytiskne přesně šest porovnávacích řádků.

Ukázkové Porovnání Swapy Časová složitost Pomocný prostor
Nejlepší (pole již seřazené) n(n-1)/2 n-1 O(n²) O (1)
Průměr (v náhodném pořadí) n(n-1)/2 n-1 O(n²) O (1)
Nejhorší (seřazeno obráceně) n(n-1)/2 n-1 O(n²) O (1)

Z této jednotné řady čísel vyplývají tři důsledky:

  • Výběrové řazení není adaptivní. Seřazený vstup stojí přesně tolik jako obrácený vstup, takže neexistuje žádná zkratka s předčasným ukončením tohoto typu. bublinové řazení nabízí.
  • Počet výměn je silnou stránkou algoritmu. Proběhne maximálně n-1 výměn, což je mnohem méně než kvadratický počet tahů, které mohou provést jiné jednoduché typy.
  • Využití paměti je konstantní. Potřebné jsou pouze čítače smyček a dvě dočasné proměnné index a smallerNumber, takže pomocný prostor je O(1) a řazení probíhá na místě.

Praktickým limitem je kvadratický růst. Zdvojnásobení velikosti pole zhruba čtyřnásobně zvýší porovnávací práci, takže výběrové řazení je vhodné spíše pro výuku, malá pole a vložený kód než pro produkční datové sady, kde jsou správnou volbou algoritmy O(n log n).

Výhody a nevýhody výběrového řazení

Pochopení toho, kde algoritmus pomáhá a kde škodí, usnadňuje rozhodnutí, kdy je rozumné ho použít.

Výhody

  • Logika je krátká a čitelná, a proto se jedná o standardní cvičení pro první třídění vedle řazení řazení.
  • Řadí se na místě, takže se nepřiděluje žádné druhé pole a využití paměti se vstupem neroste.
  • Provede maximálně n-1 zápisů do pole, což je důležité pro úložiště, kde jsou zápisy pomalé nebo opotřebovávají médium.
  • Jeho doba běhu je zcela předvídatelná, protože počet porovnání závisí pouze na délce pole.

Nevýhody

  • Každý případ je O(n²), takže algoritmus se neškáluje na velké kolekce.
  • Nedokáže detekovat již seřazené pole, a proto nikdy nedokončí předčasně.
  • Klasický tvar uvedený výše je nestabilní, takže dvě stejné hodnoty se mohou ocitnout v opačném pořadí.
  • Porovnává častěji než řazení vložením na téměř uspořádaných datech, kde se řazení vložením blíží lineárnímu času.

Stručně řečeno, zvolte výběrové řazení, když je pole malé a každý zápis je nákladný, a vyhněte se mu, kdykoli je datová sada velká nebo již téměř seřazená.

Výběrové řazení vs. Bubble-řazení vs. řazení vkládáním

Všechny tři algoritmy jsou kvadratické, srovnávací metody na místě, ale chovají se odlišně, jakmile se změní tvar vstupu.

Kritérium Výběrový osud Bubble řazení Řazení vložení
Nejlepší čas O(n²) O (n) O (n)
Průměrná a nejhorší doba O(n²) O(n²) O(n²)
V nejhorším případě výměny nebo posuny n-1 swapů n(n-1)/2 swapů Až n(n-1)/2 směn
Stabilní Ne Ano Ano
Adaptivní na seřazený vstup Ne Ano Ano
Pomocný prostor O (1) O (1) O (1)
Typické použití Nejméně potřebných zápisů Učení a vyhledávání seřazených dat Malá nebo téměř seřazená pole

Tabulka vysvětluje běžnou odpověď z pohovoru. Výběrové řazení vítězí v počtu výměn, bublinové řazení vítězí v rozpoznávání již seřazeného vstupu a řazení vkládáním je v praxi obvykle nejrychlejší z těchto tří, protože reálná data jsou často částečně seřazena. Žádné z nich nekonkuruje řazení slučováním nebo rychlému řazení, jakmile pole naroste nad několik desítek prvků.

Nejčastější dotazy

Po n-1 průchodech obsahuje netříděná oblast jeden prvek a jeden osamělý prvek je již na svém správném místě. Spuštění dalšího průchodu by nic neporovnalo, takže ohraničení smyčky zabraňuje zbytečné iteraci.

Asistenti s umělou inteligencí mohou každý průchod vyprávět slovy, vytvářet další testovací pole a počítat srovnání pro daný vstup. Vysvětlení použijte jako studijní pomůcku a před citací ověřte jakékoli tvrzení o složitosti v učebnici.

Ano. GitHub Copilot dokončí metodu z podpisu nebo komentáře. Zkontrolujte si začátek vnitřní smyčky a řádky pro výměnu sami, protože generované verze se někdy prohodí s i místo s uloženým minimálním indexem.

Zde uvedená verze je nestabilní, protože swap na dlouhou vzdálenost může přeskočit jednu stejnou hodnotu za druhou. Shiftpřevod bloku prvků namísto výměnyping zachovává původní pořadí stejných klíčů, ale za cenu dalších zápisů.

Reverse porovnání uvnitř vnitřní smyčky. Testování, zda je pole array[j] větší než pole array[index] tracks největší zbývající hodnotu, takže každý průchod posouvá maximum dopředu a hotové pole běží od nejvyšší k nejnižší hodnotě.

Ano. Rekurzivní metoda najde minimum aktuálního podpole, prohodí ho na začátek a poté se zavolá pro zbytek. Počet porovnání se nezmění, ale zásobník volání přidá O(n) prostoru, takže je preferován tvar smyčky.

Častými chybami jsou zapomenutí resetování indexu na i na začátku každého průchodu, spuštění vnitřní smyčky na i místo na i + 1 a prohozeníping array[j] namísto array[index], což ztrácí track nejmenší hodnoty.

Ne. Arrays.sort() aplikuje na primitiva quicksort s dvojitým pivotem a na objekty TimSort, s řazením vloženým na malé oddíly. Třídění výběrem se objevuje ve výukových materiálech a ručně psaném kódu spíše než ve standardní knihovně.

Shrňte tento příspěvek takto: