Алгоритъм за сортиране на вмъкване в Java с примерна програма

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

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

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

Алгоритъм за сортиране на вмъкване в Java

Какво представлява алгоритъмът за сортиране чрез вмъкване?

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

  • Премахва елемент от масив.
  • Сравнява го с най-голямата стойност в масив.
  • Премества елемента на правилното му място.

Поведението отразява начина, по който играчът на карти подрежда ръката си: всяка нова карта се взема и избутва наляво покрай всяка по-голяма карта, докато не се окаже на правилното място. Тъй като цялото изместване се случва вътре в оригиналния масив, сортирането чрез вмъкване е едновременно на място и стабилно.

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

Процес на алгоритъм за сортиране на вмъкване

Ето как процесът на алгоритъма за сортиране на вмъкване работи графично:

Анимационен trace на алгоритъма за сортиране чрез вмъкване, пренареждащ несортиран списък
Процес на алгоритъм за сортиране на вмъкване

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

Pass Ключов елемент Направени сравнения Масив след прохода
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)
Стабилен Да Да Не, във версията със стандартен масив
Adaptive Да Да, когато се използва оптимизация на флаговете Не
Записва в масива Много смени, малко върху подредени данни Много размени Точно 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, когато ключът е на позиция нула.

Да. Заменете теста за по-голямо от (greater-than) с compareTo за тип Comparable или с извикване на Comparator. Логиката на изместване остава непроменена и стабилността е запазена, което е важно, когато обектите споделят един и същ ключ за сортиране.

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