Избор Сортиране в Java Програма с пример

⚡ Умно обобщение

Сортиране на селекцията Java многократно сканира несортираната част от масив, намира най-малката оставаща стойност и я разменя на позиция, завършвайки работата с най-много n-1 размени, независимо от реда на въвеждане.

  • 🔘 Определение: Сортирането чрез селекция разделя масива на сортирана област и несортирана област при всяко преминаване.
  • ☑️ Процес: При всяко преминаване се търси в несортираната област най-ниският елемент и се разменя напред.
  • Програма: - Java примерът сортира {860, 8, 200, 9} и отпечатва всяко сравнение и размяна.
  • 🧪 Сложност: Най-добрият, средният и най-лошият случай се изпълняват за време O(n²), защото броят на сравненията никога не се свива.
  • 🛠️ Памет: Обмените се случват вътре в оригиналния масив, така че спомагателното пространство остава на O(1).
  • 📊 Поведение: Класическата версия е нестабилна, но въпреки това извършва най-малко записи от всички квадратични видове.

Избор Сортиране в Java Програма с пример

Как работи Selection Sort?

Selection Sort прилага прост алгоритъм за сортиране, както следва:

  • Алгоритъмът многократно търси най-ниския елемент.
  • Разменете текущия елемент с елемент с най-ниска стойност
  • При всяка итерация/преминаване на сортиране на селекцията елементите се разменят.

Следователно всяко преминаване третира масив като две области: сортиран блок, който расте отляво, и несортиран блок, който се свива отдясно. Алгоритъмът обхожда несортирания блок, запомня индекса на най-малката стойност, която среща, и разменя тази стойност с първата несортирана позиция.

Тъй като се извършва само една размяна на елементи на проход, масив от n елемента се подрежда след най-много n-1 размени. Това свойство е това, което отличава тази рутина от другите за начинаещи. Java алгоритми за сортиране, които преместват данни много по-често.

- tracПо-долу следва примерния масив {860, 8, 200, 9} точно както програмата в следващия раздел го отпечатва по време на изпълнение.

Pass Отпечатани сравнения Най-малката намерена стойност Масив след размяната
Начало - - 860 8 200 9
1 860 и 8, 8 и 200, 8 и 9 8 8 860 200 9
2 860 и 200, 200 и 9 9 8 9 200 860
3 200 и 860 200 8 9 200 860

Две подробности в това tracСтрува си да се спрем върху тях. Първо, третият проход все още отчита размяна, въпреки че редът не се променя, защото най-малката оставаща стойност вече се намира на текущия индекс и програмата разменя елемента със себе си. Второ, броят на сравненията намалява с едно при всеки проход (три, след това две, накрая едно), което е моделът зад цифрите за сложност по-надолу по страницата.

Java Програма за прилагане на Selection Sort

Класът по-долу се нарича SelectionSortAlgo и се намира в пакета com.guru99. Методът main() декларира примерния масив, отпечатва го, предава го на selection() за сортиране и го отпечатва отново. Помощният метод printArray() записва всички елементи на един ред, което е резултатът от четливия лог за преминаване през обработванията.

Вътре в selection(), външният цикъл маркира границата между сортираните и несортираните области, променливата index съдържа позицията на най-малката стойност, видяна досега, а трите присвоявания в края на всеки проход извършват размяната.

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

Изход:

Компилирането и изпълнението на класа генерира конзолния лог по-долу, с един блок от изхода на преминаване.

------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

Два проблема хващат начинаещите, когато изпълняват този пример за първи път. Тъй като файлът декларира package com.guru99;, източникът трябва да се намира в съответстващ com/guru99 директория, в противен случай компилаторът докладва несъответствие между пакети или имена на класове. Класът трябва да бъде стартиран с пълното си име, java com.guru99.SelectionSortAlgo, защото е обикновен java SelectionSortAlgo поражда NoClassDefFoundError.

Границите на цикъла са другият често срещан капан. Външният цикъл спира на array.length - 1 и вътрешният цикъл започва от i + 1; промяната на която и да е от границите води до допълнителен празен проход или до изключение ArrayIndexOutOfBoundsException.

Времева и пространствена сложност на сортирането чрез селекция

Вътрешният цикъл в програмата винаги се изпълнява до края на масива, така че алгоритъмът извършва един и същ брой сравнения, независимо как изглеждат данните. За масив от n елемента този общ брой е n(n-1)/2, което за извадката от четири елемента е равно на шест, а изходът по-горе наистина отпечатва точно шест реда за сравнение.

Случай Сравненията Суаповете Времева сложност Спомагателно пространство
Най-добър (масивът е вече сортиран) n(n-1)/2 п-1 O(n²) O (1)
Средно (случаен ред) n(n-1)/2 п-1 O(n²) O (1)
Най-лошо (обратно сортирано) n(n-1)/2 п-1 O(n²) O (1)

От този равномерен ред от цифри следват три следствия:

  • Сортирането чрез селекция не е адаптивно. Сортираният вход струва точно толкова, колкото и обърнатият вход, така че няма такъв пряк път с ранен изход. сортиране с балончета предлага.
  • Броят на размените е силната страна на алгоритъма. Най-много се извършват n-1 размени, което е далеч по-малко от квадратичния брой ходове, които други прости сортове могат да направят.
  • Използването на памет е константно. Необходими са само броячите на циклите и двете временни променливи index и smallerNumber, така че спомагателното пространство е O(1) и сортирането се извършва на място.

Квадратичният растеж е практическото ограничение. Удвояването на размера на масива увеличава приблизително учетворява работата по сравнение, така че сортирането чрез селекция е по-подходящо за обучение, малки масиви и вграден код, отколкото за производствени набори от данни, където алгоритмите с O(n log n) са правилният избор.

Предимства и недостатъци на сортирането по селекция

Разбирането къде алгоритъмът помага и къде вреди улеснява преценката кога е разумно да се посягне към него.

Предимства

  • Логиката е кратка и четлива, поради което е стандартно първо упражнение за сортиране, наред с вмъкване сортиране.
  • Сортира на място, така че не се заделя втори масив и използването на памет не нараства с входните данни.
  • Извършва най-много n-1 записа в масива, което е от значение за паметта, където записите са бавни или износват носителя.
  • Времето му за изпълнение е напълно предвидимо, защото броят на сравненията зависи само от дължината на масива.

Недостатъци

  • Всеки случай е O(n²), така че алгоритъмът не се мащабира до големи колекции.
  • Не може да открие вече сортиран масив и следователно никога не завършва преждевременно.
  • Класическата форма, показана по-горе, е нестабилна, така че две равни стойности могат да се окажат в обратен ред.
  • Сравнява по-често от сортирането с вмъкване върху почти подредени данни, където сортирането с вмъкване се доближава до линейно време.

Накратко, изберете сортиране по селекция, когато масивът е малък и всяко записване е скъпо, и го избягвайте, когато наборът от данни е голям или вече е близо до сортиране.

Сортиране по избор срещу Bubble Сортиране срещу сортиране с вмъкване

И трите алгоритъма са квадратични, сравняващи на място сортове, но се държат различно, след като формата на входните данни се промени.

критерий Сортиране по избор Bubble сортиране Сортиране на вмъкване
Време за най-добър случай O(n²) О (п) О (п)
Средно и най-лошо време O(n²) O(n²) O(n²)
Размени или промени в най-лошия случай n-1 суапове n(n-1)/2 размени До n(n-1)/2 смени
Стабилен Не Да Да
Адаптивен към сортиран вход Не Да Да
Спомагателно пространство O (1) O (1) O (1)
Типична употреба Най-малко необходими писания Обучение и откриване на сортирани данни Малки или почти сортирани масиви

Таблицата обяснява често срещан отговор на интервю. Сортирането с селекция печели по брой обмени, сортирането с мехурчета печели по разпознаване на вече подреден вход, а сортирането с вмъкване обикновено е най-бързото от трите на практика, защото реалните данни често са частично сортирани. Никое от тях не се конкурира със сортирането с сливане или бързото сортиране, след като масивът нарасне над няколко десетки елемента.

Въпроси и Отговори

След n-1 преминавания несортираната област съдържа един елемент, а един единствен елемент вече е на правилното си място. Изпълнението на още едно преминаване няма да сравни нищо, така че границата на цикъла избягва загубена итерация.

Асистентите с изкуствен интелект могат да преразказват всеки проход с думи, да изграждат допълнителни тестови масиви и да броят сравнения за даден вход. Използвайте обяснението като помощно средство за учене и проверете всяко твърдение за сложност в учебник, преди да го цитирате.

Да. Копилот на GitHub завършва метода от сигнатура или коментар. Проверете сами началото на вътрешния цикъл и редовете за размяна, защото генерираните версии понякога се разменят с i, вместо със съхранения минимален индекс.

Показаната тук версия е нестабилна, защото размяната на дълги разстояния може да прескочи една равна стойност след друга. Shiftпреобразуване на блока от елементи вместо размянаping запазва оригиналния ред на равните ключове, за сметка на допълнителни записи.

Reverse сравнението във вътрешния цикъл. Проверка дали array[j] е по-голям от array[index] tracks е най-голямата оставаща стойност, така че всяко преминаване премества максимума напред и готовият масив се движи от висока към ниска стойност.

Да. Рекурсивен метод намира минимума на текущия подмасив, разменя го с началото, след което се извиква за остатъка. Броят на сравненията остава непроменен, но стекът за извиквания добавя O(n) място, така че формата на цикъл е за предпочитане.

Честите грешки са забравяне да се нулира индексът на i в началото на всеки проход, стартиране на вътрешния цикъл от i вместо от i + 1 и размяна наping array[j], а не array[index], което губи track с най-малката стойност.

Не. Arrays.sort() прилага бързо сортиране с двоен пивот към примитиви и TimSort към обекти, със сортиране чрез вмъкване върху малки дялове. Сортирането чрез селекция се появява в учебните материали и ръкописния код, а не в стандартната библиотека.

Обобщете тази публикация с: