Алгоритм вставки сортування в Java з прикладом програми

⚡ Розумний підсумок

Сортування вставкою Java будує відсортовану секцію масиву по одному елементу за раз, зсуваючи більші значення праворуч, доки кожен ключ не опиниться на своєму правильному місці, що робить його ідеальним для невеликих наборів даних.

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

Алгоритм вставки сортування в Java

Що таке алгоритм сортування вставкою?

Сортування вставленням — це простий алгоритм сортування, який підходить для невеликих наборів даних. Під час кожної ітерації алгоритм:

  • Видаляє елемент із масиву.
  • Порівнює його з найбільшим значенням у масив.
  • Переміщує елемент у правильне розташування.

Така поведінка відображає те, як гравець у карти розставляє карти: кожна нова карта береться та просувається ліворуч повз кожну більшу карту, доки вона не опиниться в потрібному місці. Оскільки все зміщення відбувається всередині початкового масиву, сортування вставками є одночасно на місці та стабільним.

Він належить до тієї ж родини, що підходить для початківців Java сортування процедур як сортування бульбашками, проте зазвичай він виконує набагато менше записів у дані, які вже частково впорядковані.

Процес алгоритму вставки сортування

Ось як графічно працює алгоритм сортування вставкою:

Анімаційний trace алгоритму сортування вставками, що змінює порядок несортованого списку
Процес алгоритму вставки сортування

Анімація повторює ті самі три кроки Java виконує наведену нижче програму. Таблиця пробного запуску tracвиконує ці кроки на зразку масиву {860, 8, 200, 9} точно так, як програма виводить їх під час виконання.

Проходити Ключовий елемент Зроблені порівняння Масив після проходу
1 8 8 проти 860 8 860 200 9
2 200 200 проти 860 8 200 860 9
3 9 9 проти 860, потім 9 проти 200 8 9 200 860

Зверніть увагу, що на третьому проході потрібно два порівняння, оскільки ключ 9 має пройти повз два більші значення. Тому кількість порівнянь зростає з тим, наскільки далеко від порядку починається кожен елемент.

Java Приклад програми для сортування масиву за допомогою алгоритму сортування вставкою:

Наведена нижче програма сортує масив {860, 8, 200, 9} та виводить поточний коментар, щоб кожне порівняння та кожен зсув були видимими. Збережіть його як InsertionSortExample.java та скомпілювати його за допомогою будь-якого JDK 8 або пізнішої версії.

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

Виконання класу створює tracе показано тут. Кожен Номер сортувального пропуску Рядок позначає одну ітерацію зовнішнього циклу, а рядок, що виводиться після кожної заміни, показує масив у його стані на даний момент.

Code вихід:

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

Часова та просторова складність сортування вставками

Продуктивність сортування вставками сильно залежить від того, наскільки впорядковані вхідні дані, тому найкращий і найгірший випадки відрізняються на цілий порядок зростання.

випадок Вхідна умова Часова складність
кращий Масив вже відсортовано, тому внутрішній цикл while ніколи не виконується О (п)
середній Елементи надходять у випадковому порядку O (n²)
найгірше Масив сортується у зворотному порядку, тому кожен ключ переміщується на початок O (n²)

Використання простору набагато простіше. Тільки лічильники i, j, n та key створюються, а масив переставляється на місці, тому допоміжний простір дорівнює O(1) незалежно від того, наскільки зростає вхідний код.

Оскільки внутрішній цикл зупиняється, щойно зустрічає менше значення, сортування вставками описується як адаптивне: чим ближче вхідні дані до відсортованого порядку, тим ближче час виконання до лінійного.

Переваги та недоліки сортування вставками

Сортування вставками виживає у виробничих бібліотеках, незважаючи на випадок квадратичного середнього, оскільки його постійні множники крихітні, а поведінка передбачувана.

Переваги

  • Легко писати та легко tracвручну, що підходить як для навчання, так і для співбесід.
  • Стабільний, тому записи, що мають спільний ключ, зберігають свій початковий відносний порядок.
  • На місці, потребуючи лише O(1) додаткової пам'яті понад вхідний масив.
  • Адаптивний, що досягає O(n) для даних, які вже майже відсортовані.
  • Онлайн, тобто він може сортувати список, поки нові елементи все ще надходять.

Недоліки

  • Квадратичний час для випадкових або обернено впорядкованих вхідних даних робить його непридатним для великих масивів.
  • Кожне зсувне перенесення записує дані в масив, тому воно переміщує більше даних, ніж сортування вибором.
  • Сортування злиттям та швидке сортування комфортно перевершують його, коли на вхідних даних проходить кілька десятків елементів.

Практичне правило полягає в тому, щоб використовувати сортування вставками, коли масив малий, коли дані майже впорядковані або коли сортування за принципом «розділяй і володарюй» скоротило розділ до кількох елементів.

Сортування вставкою проти Bubble-сортування проти сортування вибором

Усі три алгоритми є квадратичними порівняннями, проте вони відрізняються стабільністю, тим, як вони реагують на впорядковані вхідні дані, та кількістю виконуваних ними записів.

Критерії Сортування вставки Bubble Сортування Сортування вибору
Найкращий випадок О (п) O(n) з прапорцем раннього виходу O (n²)
Середній та найгірший випадок O (n²) O (n²) O (n²)
Додатковий простір O (1) O (1) O (1)
Стабільний Так Так Ні, у стандартній версії масиву
Адаптивний Так Так, коли використовується оптимізація прапорців Немає
Записує в масив Багато змін, мало на впорядкованих даних Багато обмінів Рівно n-1 обмінів

Сортування вибором перемагає, коли запис є ресурсоємним, оскільки воно виконує найменшу кількість замін. Сортування вставками перемагає майже скрізь у такому масштабі, особливо на частково впорядкованих даних, тому бібліотечні сортування, такі як наведене нижче, загальний Java вправи і внутрішні механізми JDK перемикаються на нього для дуже малих розділів.

Поширені запитання

Перший елемент сам по собі вже є відсортованим підмасивом довжини один. Починаючи з індексу 1, цикл завжди має щось для порівняння, тому ключ у позиції i вставляється в упорядкований блок ліворуч від нього.

Асистенти ШІ можуть рядок за рядком розповідати пробний пробіг, генерувати додаткові тестові масиви та оцінювати зростання Big O з вихідного коду. Ставтеся до пояснення як допоміжного засобу для навчання та перевіряйте твердження про складність у підручнику, перш ніж цитувати їх.

Так. Копілот GitHub завершує стандартне сортування вставкою з сигнатури методу або коментаря. RevПерегляньте граничні умови самостійно, оскільки згенеровані цикли іноді використовують j >= 0 або j > -1 несумісно з навколишнім кодом.

Бінарне сортування вставками знаходить точку вставки за допомогою бінарного пошуку замість лінійного сканування, скорочуючи кількість порівнянь на елемент з O(n) до O(log n). Робота зсуву залишається незмінною, тому загальна часова складність залишається O(n²).

Так. Рекурсивна версія сортує перші n-1 елементів, а потім вставляє останній елемент у цей відсортований префікс. Це відповідає ітеративній часовій складності, але додає O(n) місця в стеку, тому на практиці краща версія з циклом.

Частково. Швидке сортування з подвійною опорою, яке використовується для примітивів, повертається до сортування вставками на дуже малих розділах, а TimSort, що використовується для об'єктів, сортує короткі серії за допомогою двійкового сортування вставками перед їх об'єднанням.

Частими помилками є запуск зовнішнього циклу з 0, запис arr[j] = key замість arr[j+1] = key та пропуск захисного символу j > -1, що викликає виняток ArrayIndexOutOfBoundsException, коли ключ знаходиться в нульовій позиції.

Так. Замініть перевірку "більше ніж" на compareTo для типу Comparable або на виклик Comparator. Логіка зсуву залишається незмінною, а стабільність зберігається, що важливо, коли об'єкти мають однаковий ключ сортування.

Підсумуйте цей пост за допомогою: