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

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

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

  • 🔄 Основен принцип: Сравнявайте всяка съседна двойка и разменяйте, когато лявата стойност надвишава дясната стойност, като избутвате най-големия елемент в края на всеки проход.
  • 🧮 Структура на паса: Масив от n елемента се нуждае от най-много n-1 преминавания, като всяко преминаване скъсява несортираната област с една позиция.
  • Java Изпълнение: Два вложени for цикъла плюс временна променлива извършват размяната, без да се изисква допълнително разпределение на масив.
  • Техника за оптимизация: Булев разменен флаг прекратява външния цикъл преждевременно, намалявайки най-добрия случай от квадратично към линейно време.
  • Профил на сложност: Най-лошото и средно време е O(n²), най-добрият случай е O(n) при оптимизация, а спомагателното пространство остава на O(1).
  • Сравнение на алгоритми: Бързото сортиране и сортирането с купчина се представят по-добре Bubble Сортиране на големи набори от данни, но все пак BubblСортирането остава стабилно.
  • 🎯 Практическа употреба: Изберете Bubble Сортиране за обучение, малки масиви или почти сортирани данни.

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

Какво е Bubblд Сортиране?

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

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

В тази статия ще създадем Java програма за внедряване Bubble Сортиране. Проверете резултата от кода, който ще ви помогне да разберете логиката на програмата, след което прегледайте оптимизираната версия и последващия анализ на сложността.

Как ли BubblРаботи ли алгоритъмът за сортиране?

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

Целият процес може да бъде разделен на четири повтарящи се стъпки:

  1. Сравнете: Сравнете елемента с индекс j-1 с елемента с индекс j.
  2. Размяна: Ако левият елемент е по-голям от десния елемент, разменете двете стойности, използвайки временна променлива.
  3. Advance: Преместете се с една позиция надясно и повторете, докато достигнете края на несортираната област.
  4. Повторете: Започнете ново преминаване през регион, който е с един елемент по-къс, и спрете след n-1 преминавания или когато преминаването не извършва размени.

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

Pass Масив в началото на прохода Извършени сравнения Масив в края на прохода Елементът е заключен
1 860, 8, 200, 9 3 8, 200, 9, 860 860
2 8, 200, 9, 860 2 8, 9, 200, 860 200
3 8, 9, 200, 860 1 8, 9, 200, 860 9
4 8, 9, 200, 860 0 8, 9, 200, 860 8

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

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

Преди писане Java синтаксис, това помага да се изрази логиката в езиково неутрален псевдокод. Версията по-долу включва флага за ранно излизане, така че обхваща както класическото, така и оптимизираното поведение.

procedure bubbleSort(array A, integer n)
    for i from 0 to n - 2 do
        swapped := false
        for j from 1 to n - i - 1 do
            // compare the adjacent pair
            if A[j - 1] > A[j] then
                swap A[j - 1] and A[j]
                swapped := true
            end if
        end for
        // no swap in a full pass means the array is sorted
        if swapped = false then
            break
        end if
    end for
end procedure

Външният цикъл контролира броя на проходите, а вътрешният цикъл контролира сравненията в рамките на един проход. Горната граница на вътрешния цикъл е n – i – 1, защото последните i позиции вече съдържат крайните си стойности.

Java Програма за изпълнение Bubble Сортиране

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

package com.guru99;

public class BubbleSort {

    public static void main(String[] args)
    {
        int arr[] = {860, 8, 200, 9};

        System.out.println("---Array BEFORE Bubble Sort---");

        printArray(arr);

        bubbleSort(arr); //sorting array elements using bubble sort

        System.out.println("---Array AFTER Bubble Sort---");

        printArray(arr);

    }

    static void bubbleSort(int[] array)
    {
        int n = array.length;
        int temp = 0;
        for(int i = 0; i < n; i++) // Looping through the array length
        {   System.out.println("Sort Pass Number " + (i + 1));
            for(int j = 1; j < (n - i); j++)
            {
                System.out.println("Comparing " + array[j - 1] + " and " + array[j]);
                if(array[j - 1] > array[j])
                {
                    //swap elements
                    temp = array[j - 1];
                    array[j - 1] = array[j];
                    array[j] = temp;
                    System.out.println(array[j] + " is greater than " + array[j - 1]);
                    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();

    }
}

Изход:

---Array BEFORE Bubble Sort---
860 8 200 9
Sort Pass Number 1
Comparing 860 and 8
860 is greater than 8
Swapping Elements: New Array After Swap
8 860 200 9
Comparing 860 and 200
860 is greater than 200
Swapping Elements: New Array After Swap
8 200 860 9
Comparing 860 and 9
860 is greater than 9
Swapping Elements: New Array After Swap
8 200 9 860
Sort Pass Number 2
Comparing 8 and 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 8 and 9
Sort Pass Number 4
---Array AFTER Bubble Sort---
8 9 200 860

Code обяснение: - сортиране с мехурчета Методът получава масива чрез препратка, така че извикващата страна вижда сортирания резултат без връщана стойност. Променливата ТЕМП съдържа една стойност по време на размяната на три реда, поради което алгоритъмът се нуждае само от O(1) допълнителна памет. Изразът n – i във вътрешния цикъл условието гарантира, че вече сортираните позиции в опашката никога няма да бъдат посетени отново.

Оптимизиран Bubble Сортиране на програмата в Java

Програмата по-горе винаги изпълнява n-1 преминавания, дори когато масивът се сортира рано. Добавянето на един булев флаг коригира тази неефективност. Ако пълното преминаване завърши без нито едно разместване, масивът е гарантирано сортиран и външният цикъл може да спре незабавно.

package com.guru99;

public class OptimizedBubbleSort {

    public static void main(String[] args) {
        int arr[] = {5, 12, 33, 47, 58};
        bubbleSort(arr);
        System.out.println(java.util.Arrays.toString(arr));
    }

    static void bubbleSort(int[] array) {
        int n = array.length;
        int passes = 0;
        for (int i = 0; i < n - 1; i++) {
            boolean swapped = false;
            for (int j = 1; j < n - i; j++) {
                if (array[j - 1] > array[j]) {
                    int temp = array[j - 1];
                    array[j - 1] = array[j];
                    array[j] = temp;
                    swapped = true;
                }
            }
            passes++;
            // Early exit: the array is already sorted
            if (!swapped) {
                break;
            }
        }
        System.out.println("Passes executed: " + passes);
    }
}

Изход:

Passes executed: 1
[5, 12, 33, 47, 58]

Входният масив вече беше сортиран, така че оптимизираната версия завърши след едно преминаване вместо след четири. При почти сортирани данни тази промяна превръща квадратичното натоварване в почти линейно, което е основната причина. BubblСортирането все още се появява в реалния код от време на време.

Времева сложност и пространствена сложност на Bubble Сортиране

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

Сценарий Входно условие Сложност във времето Сложност на пространството
Най-добър случай Масивът вече е сортиран, оптимизирана версия О (п) O (1)
Среден случай Елементи в произволен ред O(n²) O (1)
Най-лошия случай Масив, сортиран в обратен ред O(n²) O (1)

Тъй като всеки обмен се случва в оригиналния масив и се използва само една временна променлива, BubblСортирането е алгоритъм на място с O(1) спомагателно пространство. То е и стабилно сортиране, което означава, че два записа, съдържащи един и същ ключ, запазват първоначалния си относителен ред след сортиране.

Предимства и недостатъци на Bubble Сортиране

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

Предимства

  • Простота: Логиката се побира в приблизително десет реда, което улеснява правилното писане при условия на интервю.
  • Работа на място: Не се заделя спомагателен масив, така че използването на памет не нараства с размера на входните данни.
  • стабилност: Равните ключове запазват първоначалния си ред, което е важно при сортиране на записи по вторично поле.
  • Ранно откриване на излизане: Флагът за размяна идентифицира вече сортиран масив в един проход.

Недостатъци

  • Квадратичен растеж: Сортирането на 10 000 елемента изисква близо 50 милиона сравнения в най-лошия случай.
  • Прекомерно пише: Алгоритъмът извършва много повече суапове от сортирането чрез селекция, което е скъпоструващо за паметта с бавни операции за запис.
  • Слаба мащабируемост: Производствените натоварвания почти винаги предпочитат Quicksort, Merge Sort или вградения метод Arrays.sort.

💡 Съвет: В производството Java код, предпочитам масиви.sort() за примитиви и Колекции.сортиране() за списъци. И двата използват високо настроени алгоритми, съответно Dual-Pivot Quicksort и TimSort, които превъзхождат ръкописен Bubble Сортиране по порядъци на величината.

Bubble Сортиране срещу други видове сортиране Algorithms

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

алгоритъм Най -добрият случай Среден случай Най-лошия случай Космос Стабилен
Bubble Сортиране О (п) O(n²) O(n²) O (1) Да
Сортиране на избора O(n²) O(n²) O(n²) O (1) Не
Сортиране по вмъкване О (п) O(n²) O(n²) O (1) Да
Бързо сортиране O(n log n) O(n log n) O(n²) O (log n) Не
Сортиране на купчина O(n log n) O(n log n) O(n log n) O (1) Не

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

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

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

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

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

Reverse операторът за сравнение във вътрешния цикъл. Промяна ако (масив[j-1] > масив[j]) да се ако (масив[j-1] < масив[j])Всеки друг ред от програмата остава непроменен.

Да. Заменете оператора „по-голямо от“ с compareTo() за низови стойности или с извикване на Comparator за персонализирани обекти. Структурата на обграждащия цикъл и логиката на размяната остават идентични.

Да. Асистентите с изкуствен интелект надеждно произвеждат работещи Bubble Сортирайте кода, защото шаблонът е изключително често срещан в обучителните данни. Винаги проверявайте границите на цикъла и тествайте с обърнати и дублирани стойности, преди да се доверите на резултата.

Да. Интервюиращите все още го използват, за да тестват циклично разсъждение и анализ на сложността. Разбирането на алгоритъма ви позволява също да прецените дали генерираният от изкуствен интелект код за сортиране е ефикасен, а не просто функционален.

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