Wprowadzenie do algorytmów sortowania w Javie

Sortowanie informacji w określonej kolejności, często w ramach struktury podobnej do tablicy, polega na ich uporządkowaniu. Możesz użyć różnych wymagań dotyczących sekwencji, popularne są sortowanie liczb od najmniejszej do największej lub odwrotnie, lub leksykograficzne sortowanie ciągów. Zajmiemy się różnymi algorytmami, od nieskutecznych, ale intuicyjnych alternatyw, po wydajne algorytmy skutecznie zaimplementowane w Javie i innych językach, jeśli jesteś zainteresowany tym, jak działa sortowanie.

Różne algorytmy sortowania w Javie

Istnieją różne algorytmy sortowania i nie wszystkie są równie skuteczne. Aby je porównać i sprawdzić, które z nich są najskuteczniejsze, przeanalizujemy ich złożoność czasową.

  1. Sortowanie przez wstawianie
  2. Sortowanie bąbelkowe
  3. Sortuj wybór
  4. Scal sortowanie
  5. Heapsort

1. Wstawianie Sortuj

Koncepcja stojąca za wstawianiem Sortuje dzieli zakres na podpariały, które są posortowane i nieposortowane. Część sklasyfikowana znajduje się na początku czasu trwania 1 i odpowiada pierwszemu składnikowi (lewa strona) w tablicy. Poruszamy się po tablicy i podczas każdej iteracji rozszerzamy sklasyfikowaną część tablicy o jeden komponent. Po rozwinięciu umieszczamy świeży element w posortowanej pod-tablicy. Robimy to, przesuwając wszystkie elementy w prawo, dopóki nie stwierdzimy, że nie musimy zmieniać pierwszego elementu. Kiedy pogrubiona część jest posortowana w porządku rosnącym, na przykład w następującej tablicy, następuje:

  1. 3 5 7 8 4 2 1 9 6: Rozważ 4 i wstaw to, czego potrzebujemy. Zmieniamy się od 8> 4
  2. 2. 3 5 7 x 8 2 1 9 6
  3. 3 5 x 7 8 2 1 9 6
  4. 3 x 5 7 8 2 1 9 6
  5. 3 4 5 7 8 2 1 9 6

Kod:

public class InsertionSortEx (
public static void insertionSort(int() arr) (
for (int x = 1; x < arr.length; x++) (
int current = arr(x);
int y = x - 1;
while(y >= 0 && current < arr(y)) (
arr(y+1) = arr(y);
y--;
)
arr(y+1) = current;
)
)
public static void main(String a())(
int() arr1 = (3, 5, 7, 8, 4, 2, 1, 9, 6);
System.out.println("Before Sorting");
for(int x:arr1)(
System.out.print(x+" ");
)
System.out.println();
insertionSort(arr1);//sorting array using insertion sort
System.out.println("After Insertion Sorting");
for(int x:arr1)(
System.out.print(x+" ");
)
)
)

Wynik:

Zgodnie z tą metodą jeden element rozszerzył posortowaną część, teraz mamy pięć zamiast czterech elementów. Każda iteracja to robi, a cała tablica zostanie posortowana do końca.

Uwaga: Dzieje się tak, ponieważ musimy przenieść całą listę klasyfikowaną jeden po drugim w każdej iteracji, czyli O (n). Dla każdego komponentu w każdej tabeli musimy to zrobić, co oznacza, że ​​jest on ograniczony przez O (n 2) 2.

2. Sortowanie bąbelkowe

Jeśli pęcherzyk nie jest w wymaganej kolejności, działa poprzez wymianę sąsiednich elementów. Jest to powtarzane, dopóki wszystkie składniki nie będą w porządku od początku tablicy. Wiemy, że jeśli uda nam się wykonać całą iterację bez zamiany, wszystkie elementy w porównaniu z sąsiednimi elementami były w pożądanej kolejności, a co za tym idzie - całej tablicy. Algorytm Sortowania Bąbelkowego jest spowodowany tym, że liczby takie jak „bąbelki w górę” przechodzą w „ziemię”. Jeśli po określonej ilości ponownie przejdziesz przez instancję (4 to dobra instancja), zauważysz, że liczba powoli przesuwa się w prawo.

Kroki do sortowania bąbelkowego są następujące:

  1. 4 2 1 5 3: Tutaj pierwsze dwie liczby nie są we właściwej kolejności, dlatego musimy posortować obie liczby.
  2. 2 4 1 5 3: Po tym następna para liczb również nie jest w prawidłowej kolejności. Tak więc sortowanie następuje ponownie.
  3. 2 1 4 5 3: Te dwa są w odpowiedniej kolejności, 4 <5, dlatego nie ma potrzeby ich zamiany.
  4. 2 1 4 5 3 : Znowu musimy zamienić się w celu uzyskania prawidłowej kolejności.
  5. 2 1 4 3 5: Oto tablica wynikowa po jednej iteracji.
  6. Musimy powtórzyć ten proces ponownie, aż liczby będą we właściwej kolejności.

Kod:

public class BubbleSortExample (
public static void bubbleSort(int() arr) (
int n = arr.length;
int tmp = 0;
for(int x=0; x < n; x++)(
for(int y=1; y < (nx); y++)(
if(arr(y-1) > arr(y))(
//swap elements
tmp = arr(y-1);
arr(y-1) = arr(y);
arr(y) = tmp;
)
)
)
)
public static void main(String() args) (
int arr() =(4, 2, 1, 5, 3);
System.out.println("Array Before Bubble Sort");
for(int x=0; x < arr.length; x++)(
System.out.print(arr(x) + " ");
)
System.out.println();
bubbleSort(arr);
System.out.println("Array After Bubble Sort");
for(int x=0; x < arr.length; x++)(
System.out.print(arr(x) + " ");
)
)
)

Wynik:

Uwaga: Mogłoby skończyć się w nieskończonej pętli, gdybym użył (i)> = a (i + 1), ponieważ to połączenie nadal byłoby poprawne z równoważnymi komponentami i dlatego zawsze zamieniałbym je z jednego elementu na drugi.

3. Wybór Sortuj

Wybór sortowania dzieli tablicę na tablicę klasyfikacji, które nie są sortowane. Tym razem jednak podtablica sortująca jest tworzona przez wstawienie na końcu posortowanej tablicy minimalnego elementu nieposortowanej podtablicy, poprzez zamianę:

  1. 3 5 1 2 4
  2. 1 5 3 2 4
  3. 1 2 3 5 4
  4. 1 2 3 5 4
  5. 1 2 3 4 5
  6. 1 2 3 4 5

Kod:

public class SelectionSortEx (
public static void selectionSort(int() arr)(
for (int x = 0; x < arr.length - 1; x++)
(
int indx = x;
for (int y = x + 1; y < arr.length; y++)(
if (arr(y) < arr(indx))(
indx = y;
)
)
int smallNumber = arr(indx);
arr(indx) = arr(x);
arr(x) = smallNumber;
)
)
public static void main(String a())(
int() arr1 = (3, 5, 1, 2, 4);
System.out.println("Before Sorting");
for(int x:arr1)(
System.out.print(x+" ");
)
System.out.println();
selectionSort(arr1);
System.out.println("After Selection Sorting");
for(int x:arr1)(
System.out.print(x+" ");
)
)
)

Wynik:

Uwaga: Minimalna wartość to O (n) dla rozmiaru tablicy, ponieważ wszystkie komponenty muszą zostać sprawdzone. Dla każdego elementu tablicy musimy znaleźć minimum i ograniczyć cały proces O (n 2).

4. Scal sortowanie

Scalanie sortowania wykorzystuje rekurencję, aby rozwiązać problem metody dzielenia i podbijania skuteczniej niż wcześniej opisane algorytmy.

To drzewo pokazuje, jak działają wywołania rekurencyjne. Tablice oznaczone strzałkami w dół to tablice, dla których wywołujemy funkcję podczas łączenia tablic strzałek w górę. Następnie podążaj za strzałką do krawędzi drzewa, a następnie wróć i połącz. Mamy zakres 3 5 3 1, więc podzieliliśmy go na 3 5 4 i 2 1. Podzieliliśmy je na części, aby je posortować. Zaczynamy stapiać i sortować je, gdy schodzimy na dół.

Kod:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class MergeSort (
static void merge(int() array, int lowval, int midval, int highval)(
int x, y, k;
int() c= new int(highval-lowval+1);
k = 0;
x=lowval;
y=midval+1;
while(x<=midval && y<=highval)(
if(array(x)<=array(y))(
c(k++) = array(x++);
)
else(
c(k++) = array(y++);
)
)
while(x<=midval)(
c(k++) = array(x++);
)
while(y<=highval)(
c(k++) = array(y++);
)
k=0;
for(x = lowval; x<=highval; x++)(
array(x) = c(k++);
)
)
static void mergeSort(int() array, int lowval, int highval)(
if(highval-lowval+1>1)(
int midval = (lowval+highval)/2;
mergeSort(array, lowval, midval);
mergeSort(array, midval+1, highval);
merge(array, lowval, midval, highval);
)
)
public static void main(String() args) (
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
int size;
System.out.println("Enter the array");
try (
size = Integer.parseInt(r.readLine());
) catch (Exception e) (
System.out.println("Please Enter valid Input");
return;
)
int() array = new int(size);
System.out.println("Enter array elements");
int x;
for (x = 0; x < array.length; x++) (
try (
array(x) = Integer.parseInt(r.readLine());
) catch (Exception e) (
System.out.println("An error Occurred");
)
)
System.out.println("After Sorting");
System.out.println(Arrays.toString(array));
mergeSort(array, 0, array.length-1);
System.out.println("Before Merge Sorting");
System.out.println(Arrays.toString(array));
)
)

W tym programie poprosiliśmy użytkownika o wprowadzenie danych wejściowych. Dane wyjściowe będą sortowane w kolejności na podstawie danych wejściowych użytkownika.

Wynik:

5. Sortuj sterty

Najpierw musisz znać strukturę, na której działa Heapsort - stertę - aby zrozumieć, dlaczego działa. Będziemy konkretnie mówić o stosie binarnym, ale możesz także uogólnić to na inne konstrukcje stosu. Sterty to drzewo, które spełnia właściwość sterty, a mianowicie to, że wszystkie jego dzieci mają powiązania z każdym węzłem. Kupa też musi być prawie ukończona. Prawie pełna binarna głębokość d ma poddrzewo d-1, z tym samym rdzeniem, a każdy węzeł ma pełne, lewe poddrzewo, z lewym opadającym.

Innymi słowy, podczas przesuwania się w dół drzewa dostajesz coraz mniejszą liczbę (min-kupa) lub większą i większą (max-kupa). Oto instancja typu max-heap:

  1. 6 1 8 3 5 2 4 : Tutaj liczba obu dzieci jest mniejsza niż rodzica, dlatego nie musimy niczego zmieniać.
  2. 6 1 8 3 5 2 4: Tutaj, 5> 1, musimy je zamienić. Musimy kupować dla 5.
  3. 6 5 8 3 1 2 4: Obie liczby dzieci są mniejsze, wszystko pozostaje takie samo.
  4. 6 5 8 3 1 2 4: Tutaj 8> 6, dlatego powinniśmy je zamienić.
  5. 8 5 6 3 1 2 4: Po tej iteracji otrzymamy ten wynik.

Po ponownym powtórzeniu tego procesu otrzymamy następujące wyniki:

  • 8 5 6 3 1 2 4
  1. 4 5 6 3 1 2 8 : Zamiana
  2. 6 5 4 3 1 2 8 : Heapify
  3. 2 5 4 3 1 6 8 : Zamiana
  4. 5 2 4 2 1 6 8 : Heapify
  5. 1 2 4 2 5 6 8 : Zamiana

Kod:

public class HeapSort
(
public void sort(int arr())
(
int n = arr.length;
for (int x = n / 2 - 1; x >= 0; x--)
heapify(arr, n, x);
for (int x=n-1; x>=0; x--)
int tmp = arr(0);
arr(0) = arr(x);
arr(x) = tmp;
heapify(arr, x, 0);
)
)
void heapify(int arr(), int n, int x)
(
int largest = x;
int L = 2*x + 1;
int r = 2*x + 2;
if (L arr(largest))
largest = L;
if (r arr(largest))
largest = r;
if (largest != x)
(
int swap = arr(x);
arr(x) = arr(largest);
arr(largest) = swap;
heapify(arr, n, largest);
)
)
static void printArray(int arr())
(
int n = arr.length;
for (int x=0; x System.out.print(arr(x)+" ");
System.out.println();
)
public static void main(String args())
(
int arr() = (6, 1, 8, 3, 5, 2, 4);
int n = arr.length;
System.out.println("Before Sorting:");
printArray(arr);
HeapSort ob = new HeapSort();
ob.sort(arr);
System.out.println("After Heap Sorting:");
printArray(arr);
)
)
public class HeapSort
(
public void sort(int arr())
(
int n = arr.length;
for (int x = n / 2 - 1; x >= 0; x--)
heapify(arr, n, x);
for (int x=n-1; x>=0; x--)
int tmp = arr(0);
arr(0) = arr(x);
arr(x) = tmp;
heapify(arr, x, 0);
)
)
void heapify(int arr(), int n, int x)
(
int largest = x;
int L = 2*x + 1;
int r = 2*x + 2;
if (L arr(largest))
largest = L;
if (r arr(largest))
largest = r;
if (largest != x)
(
int swap = arr(x);
arr(x) = arr(largest);
arr(largest) = swap;
heapify(arr, n, largest);
)
)
static void printArray(int arr())
(
int n = arr.length;
for (int x=0; x System.out.print(arr(x)+" ");
System.out.println();
)
public static void main(String args())
(
int arr() = (6, 1, 8, 3, 5, 2, 4);
int n = arr.length;
System.out.println("Before Sorting:");
printArray(arr);
HeapSort ob = new HeapSort();
ob.sort(arr);
System.out.println("After Heap Sorting:");
printArray(arr);
)
)

Wynik:

Możesz go przeglądać od punktu do poziomu wykresu, od lewej do prawej. Osiągnęliśmy tutaj, że gdy mamy k-ty składnik w tablicy, pozycja jego elementów potomnych wynosi 2 \ * k + 1 i 2 \ * k + 2 (zakładając, że indeksowanie zaczyna się od 0). Możesz to monitorować. Pozycja rodzica to zawsze (k-1) / 2 dla k-tego komponentu. Możesz łatwo „maksymalnie zwiększyć” każdy zakres, ponieważ o tym wiesz. Sprawdź, czy jedno z jego dzieci jest niższe niż dla każdego elementu. Jeśli tak, sparuj jednego rodzica i powtórz ten krok rekurencyjnie z rodzicem.

Uwaga: Ponieważ iteracja pętli for w całej tablicy powoduje heapSort) (oczywiście O (N), stworzyłaby ogólną złożoność Heapsort O (nlog n). Heapsort ma typ na miejscu, co oznacza, że ​​wymaga O ( 1) więcej miejsca niż Sortuj według scalania, ale ma pewne wady, takie jak trudne podobieństwa.

Wniosek - algorytmy sortowania w Javie

Sortowanie jest bardzo rozpowszechnioną procedurą z zestawami danych, czy to do dalszej analizy, przyspieszenia wyszukiwania z bardziej efektywnymi algorytmami opartymi na posortowanych informacjach, filtrowaniu informacji itp. Sortowanie jest poparte przez kilka języków, a interfejsy często zaciemniają to, co robi programista.

Polecane artykuły

Jest to przewodnik po sortowaniu algorytmów w Javie. Tutaj omawiamy różne rodzaje sortowania w Javie wraz z ich algorytmami. Możesz także przejrzeć nasze inne sugerowane artykuły -

  1. Scal sortowanie algorytmów w Javie
  2. JComboBox w Javie
  3. StringBuffer w Javie
  4. JTextField w Javie
  5. Sortuj sterty w Pythonie
  6. Algorytmy szybkiego sortowania w Javie
  7. Kompletny przewodnik po sortowaniu w C # z przykładami
  8. Sortowanie algorytmów w JavaScript
  9. Przewodnik po przykładach algorytmu C ++
  10. Kompletny przewodnik po algorytmach sortowania w Pythonie