Szybkie sort w Javie wyjaśnił

Szybkie sort w Javie wyjaśnił
Quick Sort, napisany również jako Quicksort, to schemat sortowania listy, który wykorzystuje paradygmat podziału i koniunktury. Istnieją różne schematy do szybkiego sortowania, wszystkie wykorzystujące paradygmat podziału i koniunktury. Przed wyjaśnieniem szybkiego sortowania czytelnik musi znać konwencję o połowę listy lub podpisów oraz medianę trzech wartości.

Konwencja o połowę

Gdy liczba elementów na liście jest równa, zmniejszenie listy oznacza, że ​​dosłowna pierwsza połowa listy to pierwsza połowa, a dosłowna druga połowa listy to druga połowa. Środkowy (środkowy) element całej listy jest ostatnim elementem pierwszej listy. Oznacza to, że środkowy wskaźnik ma długość / 2 - 1, ponieważ zliczanie indeksu zaczyna się od zera. Długość to liczba elementów na liście. Na przykład, jeśli liczba elementów wynosi 8, wówczas pierwsza połowa listy ma 4 elementy, a druga połowa listy ma również 4 elementy. W porządku. Ponieważ zliczanie indeksu rozpoczyna się od 0, środkowy indeks wynosi 3 = 8/2 - 1.

A co z sprawą, gdy liczba elementów na liście lub liście jest dziwna? Na początku długość jest nadal podzielona przez 2. Według konwencji liczba elementów w pierwszej połowie tego podziału wynosi długość / 2 + 1/2. Liczenie indeksu zaczyna się od zera. Środkowy indeks jest podawany przez długość / 2 - 1/2. Jest to uważane za średnie termin, według konwencji. Na przykład, jeśli liczba elementów na liście wynosi 5, wówczas środkowy indeks to 2 = 5/2 - 1/2. I w pierwszej połowie listy są trzy elementy i dwa elementy w drugiej połowie. Środkowy element całej listy jest trzecim elementem przy indeksie, 2, który jest wskaźnikiem środkowym, ponieważ zliczanie indeksu zaczyna się od 0.

Podział w ten sposób jest przykładem arytmetyki całkowitej.

Mediana trzech wartości

Pytanie: Jaka jest mediana sekwencji:

C B a

Rozwiązanie:
Ułóż listę w kolejności rosnącej:

A B c

Średnia termin, B, to mediana. Jest to wielkość, która leży między pozostałymi dwoma wielkościami.

Poszukiwanie mediany na liście nie jest takie. Na przykład na liście 19 elementów nieporządonych, mediana dla pierwszego elementu, elementu środkowego i ostatniego elementu może być wymagana. Te trzy wartości mogą nie być w kolejności rosnącej; I tak należy wziąć pod uwagę ich indeksy.

Z szybkim sortym, mediana dla całej listy i podmiotów jest wymagana. Pseudocode do poszukiwania mediany trzech wartości rozmieszczonych na liście (tablica) to:

mid: = ⌊ (niski + wysoki) / 2⌋
Jeśli ARR [MID] < arr[low]
zamiana ARR [niski] z ARR [MID]
Jeśli ARR [HIGH] < arr[low]
zamiana ARR [niski] z ARR [High]
Jeśli ARR [MID] < arr[high]
zamiana ARR [MID] z ARR [High]
Pivot: = arr [high]

Termin „ARR” oznacza tablicę. Ten segment kodu szuka mediany, a także sortowanie. Ten segment kodu wygląda prosto, ale może być dość mylące. Zwróć więc uwagę na następujące wyjaśnienie:

Sortowanie w tym samouczku wytworzy listę, w której pierwsza wartość jest najmniejszą wartością, a ostatnia wartość jest największą wartością. Z alfabetem A jest mniejsze niż z.

Tutaj obrotem jest wynikowa mediana. Niski jest najniższym wskaźnikiem listy lub sub-list (niekoniecznie dla najniższej wartości); Wysoki jest najwyższym wskaźnikiem listy lub podpisów (niekoniecznie dla najwyższej wartości), a środkowy jest konwencjonalnym wskaźnikiem środkowym (niekoniecznie dla środkowej wartości całej listy).

Tak więc mediana, którą należy uzyskać.

W kodzie pierwsza jest konwencjonalna indeks środkowy. Na tym początku lista jest niepohamowana. Porównanie i pewne przegrupowanie w kolejności rosnącej trzech wartości mają się odbyć w tym samym czasie. Pierwsze podtrzymanie IF porównuje wartość dla najniższego wskaźnika i wartości środkowego indeksu. Jeśli wskaźnik środkowy jest mniejszy niż w przypadku najniższego wskaźnika, wówczas dwie wartości zamieniają pozycje. To zaczyna się sortować i zmienia rozmieszczenie wartości na liście lub liście. Drugie podatność IF porównuje wartość dla najwyższego wskaźnika i najniższego wskaźnika. Jeśli najwyższy wskaźnik jest mniejszy niż najniższy wskaźnik, dwie wartości zamieniają pozycje. To prowadzi do sortowania i zmiany rozmieszczenia wartości na liście lub liście. Trzecie podatność IF porównuje wartość dla środkowego wskaźnika i najwyższego wskaźnika. Jeśli najwyższy wskaźnik jest mniejszy niż wskaźnik środkowy, dwie wartości zamieniają pozycje. Tutaj może wystąpić również pewne sortowanie lub przegrupowanie. Ten trzeci klimatyzacja IF nie jest jak poprzednie dwa.

Na końcu tych trzech swapów środkowa wartość trzech danych wartości byłaby [wysoka], której oryginalna treść mogła zostać zmieniona w segmencie kodu. Rozważmy na przykład nieposortowaną sekwencję:

C B a

Wiemy już, że mediana to B. Należy to jednak udowodnić. Celem tutaj jest uzyskanie mediany tych trzech wartości za pomocą powyższego segmentu kodu. Pierwszy podtrzymanie IF porównuje B i C. Jeśli B jest mniejsze niż C, wówczas pozycje B i C należy zamienić. B jest mniejsze niż C, więc nowe porozumienie staje się:

B c a

Zauważ, że wartości dla najniższego indeksu i środkowego indeksu uległy zmianie. Drugi podatność IF porównuje A i B. Jeśli A jest mniejsze niż B, wówczas pozycje A i B muszą zostać zamienione. A jest mniejsze niż B, więc nowe porozumienie staje się:

A c b

Zauważ, że wartości dla najwyższego wskaźnika i najniższy wskaźnik zmieniły się. Trzeci hodowla IF porównuje C i B. Jeśli C jest mniejsze niż B, wówczas pozycje C i B muszą zostać zamienione. C jest nie mniej niż b, więc nie ma zamiany. Nowe porozumienie pozostaje jako poprzednie, to znaczy:

A c b

B to mediana, czyli [wysokie] i jest to obrot. Zatem obrotowie rodzi się na skrajnym końcu listy lub liści.

Funkcja zamiany

Inną funkcją potrzebną szybkiego sortowania jest funkcja zamiany. Funkcja zamiany wymienia wartości dwóch zmiennych. Pseudokod dla funkcji zamiany to:

Zdefiniuj swap (x, y)
TEMP: = x
x: = y
y: = temp

Tutaj X i Y odnoszą się do rzeczywistych wartości, a nie kopii.

Sortowanie w tym artykule wytworzy listę, w której pierwsza wartość jest najmniejszą wartością, a ostatnia wartość jest największą wartością.

Treść artykułu

  • Algorytm szybkiego sortowania
  • Pseudocode partycji
  • Ilustracja szybkiego rodzaju
  • Kodowanie Java
  • Wniosek

Algorytm szybkiego sortowania

Normalnym sposobem sortowania listy nieposortowanej jest rozważenie dwóch pierwszych wartości. Jeśli nie są w porządku, uporządkuj je. Następnie rozważ pierwsze trzy wartości. Zeskanuj pierwsze dwa, aby zobaczyć, gdzie pasuje trzecia wartość i odpowiednio dopasowuje. Następnie rozważ pierwsze cztery wartości. Zeskanuj pierwsze trzy wartości, aby zobaczyć, gdzie pasuje czwarta wartość i odpowiednio pasuje. Kontynuuj tę procedurę, aż cała lista nie zostanie posortowana.

Ta procedura, znana również jako sortowanie siły brutalnej, w języku komputerowym, jest zbyt wolna. Algorytm szybkiego sortowania ma znacznie szybszą procedurę.

Kroki algorytmu Quicksort są następujące:

  1. Upewnij się, że na liście niepotrzebnych jest co najmniej 2 liczby.
  2. Uzyskaj szacunkową wartość centralną dla listy, zwana obrotem. Mediana, jak opisano powyżej, jest jednym ze sposobów uzyskania obrotu. Różne sposoby mają ich zalety i wady. - Zobaczymy później.
  3. Partycjonuj listę. Oznacza to, umieść obrotę na liście. W taki sposób wszystkie elementy po lewej są mniej niż wartość obrotu, a wszystkie elementy po prawej. Istnieją różne sposoby podziału. Każda metoda partycji ma swoje zalety i wady. Partycjonowanie dzieli się w paradygmacie podziału i koniunktury.
  4. Powtórz kroki 1, 2 i 3 rekurencyjnie dla nowych par sub-list, które pojawiają się, dopóki cała lista nie zostanie sortowana. To podbija paradygmat podziału i koniunktury.

Szybki sort Pseudocode to:

Algorytm Quicksort (ARR, niski, wysoki) jest
przepływam < high then
Pivot (niski, wysoki)
P: = partycja (ARR, niska, wysoka)
Quicksort (ARR, Low, P - 1)
Quicksort (ARR, P + 1, High)

Pseudocode partycji

Pseudokod partycji użyty w tym samouczku to:

partycja algorytmu (ARR, niska, wysoka) jest
Pivot: = arr [high]
I: = niski
J: = wysoki
Do
Do
++I
While (ARR [i] < pivot)
Do
--J
while (ARR [J]> Pivot)
Jeśli ja < j)
zamiana ARR [i] z ARR [J]
podczas gdy ja < j)
zamiana ARR [i] z ARR [High]
powrót i

Na ilustracji Szybkiego sortowania poniżej ten kod jest używany:

Ilustracja szybkiego rodzaju

Rozważ następującą listę nieporządkową (tablicę) liter alfabetycznych:

Q w e r t y u i o p

Według kontroli posortowana lista to:

E i o p q r t u y

Porodowa lista zostanie teraz udowodniona, korzystając z powyższego algorytmu i segmentów pseudokodowych, z listy niepohamowanej:

Q w e r t y u i o p

Pierwszy obrot jest określany na podstawie arr [0] = q, arr [4] = t i arr [9] = p i jest identyfikowany jako q i umieszczony po skrajnym prawym prawym liście listy. Tak więc lista z dowolnym sortowaniem funkcji obrotowych staje się:

P w e r t y u i o q

Obecny obrót to q. Procedura obrotu wykonała małe sortowanie i umieściła P w pierwszej pozycji. Powstała lista musi zostać poddana zmianie (podzielona), tak że wszystkie elementy po lewej stronie są mniejsze, a następnie obrotowe i wszystkie elementy po prawej stronie obrotu są równe lub większe niż obrót. Komputer nie może wykonywać partycjonowania przez inspekcję. Tak więc za pomocą indeksów i powyższego algorytmu partycji.

Niskie i wysokie indeksy to teraz 0 i 9. Tak więc komputer rozpocznie się od skanowania z indeksu 0, aż osiągnie indeks, którego wartość jest równa lub większa niż obrot. Będzie również skanować z wysokiego (prawego) końca, wskaźnik 9, schodząc w dół, aż do osiągnięcia indeksu, którego wartość jest mniejsza lub równa obrotowi i zatrzyma się tam tymczasowo. Oznacza to dwie pozycje zatrzymania. Jeśli I, zmienna indeksu przyrostowa, od niskiej nie jest jeszcze równa lub większa niż zmienna wskaźnika malejąca, j z wysokiej, wówczas te dwie wartości są zamieniane. W obecnej sytuacji skanowanie z obu końca. Lista staje się więc:

P o e r t y u i w q

Pivot jest nadal q. Skanowanie w przeciwnych kierunkach trwa i zatrzymuje się odpowiednio. Jeśli nie jest jeszcze równe lub większe niż J, to dwie wartości, przy których skanowanie z obu końców są zamieniane. Tym razem skanowanie z obu końców zatrzymało się w R i I. Tak więc układ listy staje się:

P o e i t y u r w q

Pivot jest nadal q. Skanowanie w przeciwnych kierunkach trwa i zatrzymuje się odpowiednio. Jeśli nie jest jeszcze równe lub większe niż J, to dwie wartości, przy których zatrzymano skanowanie, są zamieniane. Tym razem skanowanie z obu końców zatrzymało się na T dla I i I dla J. Ja i J spotkałem lub skrzyżowałem. Więc nie może być zamiany. Lista pozostaje taka sama jak:

P o e i t y u r w q

W tym momencie Pivot, Q, należy umieścić w swojej ostatecznej pozycji w sortowaniu. Odbywa się to poprzez zamianę ARR [i] z ARR [High], zamianę t i q. Lista staje się:

P o e i q y u r w t

W tym momencie zakończyło się partycjonowanie całej listy. Pivot = Q odegrał swoją rolę. Istnieją teraz trzy sub-listy, które są:

P o e i q y u r w t

Partycja to podział i podbicie (sortowanie) w paradygmacie. Q jest we właściwej pozycji sortowania. Każdy element po lewej stronie jest mniejszy niż Q, a każdy element po prawej stronie Q jest większy niż Q. Jednak lewa lista wciąż nie jest sortowana; A odpowiednia lista wciąż nie jest sortowana. Funkcję całego szybkiego sortowania musi być nazywana rekurencyjnie, aby sortować lewą podpisę i prawą podpis. To przywołanie szybkiego rodzaju musi kontynuować; Nowe podpiski będą się rozwijać, dopóki cała oryginalna lista nie zostanie całkowicie sortowana. Dla każdego przywoływania funkcji szybkiego sortowania lewa podpis. Dla każdej sub-listy należy uzyskać nowy punkt zwrotny.

Dla podrzędnej:

P o e i

Pivot (mediana) dla P, O i I jest określone. Pivot byłby O. W przypadku tej sub-listy i odnoszącej się do pełnej listy nowy ARR [niski] to ARR [0], a nowy ARR [High] jest ostatnim ARR [i-1] = ARR [4-1] = ARR [3], gdzie i jest końcowym wskaźnikiem obrotu z poprzedniej partycji. Po wywołaniu funkcji PIVOT () nowa wartość obrotu, Pivot = O. Nie myl między funkcją obrotu a wartością obrotu. Funkcja obrotu może wykonywać małe sortowanie i umieszczać obrót po skrajnym prawym prawym miejscu pod liście. Ta sub-lista staje się,

I P E O

W tym schemacie obrotek zawsze kończy się na prawym końcu sub-listy lub listy po jej wywołaniu funkcji. Skanowanie z obu końców rozpoczyna się od ARR [0] i ARR [3], aż ja i J nie spotkają się lub krzyżują. Porównanie odbywa się z Pivot = O. Pierwsze przystanki są na P i E. Są zamienione, a nowa podpisa staje się:

I E P O

Skanowanie z obu końca. Teraz ja i J spotkałem lub krzyżuje. Tak więc podpisa pozostaje taka sama jak:

I E P O

Podział pod liście lub listę kończy. Tak więc nowe wartości dla ARR [i] i arr [high] są zamieniane. To znaczy, p i o są zamienione. Nowa podpisa staje się:

I E O P

O jest teraz na ostatecznej pozycji dla całej listy. Jego rola jako obrotu się zakończyła. Podpisa jest obecnie podzielona na trzy kolejne listy, które są:

I E O P

W tym momencie należy wywołać szybką pierwszą prawą sub-listę. Jednak nie zostanie to wezwane. Zamiast tego zostanie odnotowane i zastrzeżone, które zostaną nazwane później. Ponieważ wykonywano instrukcje funkcji partycjonowania, od góry funkcji jest to szybki sort dla lewej podpisu, który należy nazwać teraz (po wywołaniu Pivot ()). Zostanie wezwany do listy:

TJ

Zacznie się od poszukiwania mediany I i E. Tutaj arr [niski] = i, arr [mid] = i i arr [high] = e. Więc mediana, obrotu, powinna być określona przez algorytm obrotu jako, i. Jednak powyższy pseudokod obrotowy określi obrotek jako E. Ten błąd występuje tutaj, ponieważ powyższy pseudokod jest przeznaczony dla trzech elementów, a nie dwóch. W poniższej implementacji istnieje pewna korekta kodu. Podpisa staje się,

E i

Pivot zawsze kończy się na prawym końcu sub-listy lub listy po wywołaniu funkcji. Skanowanie z obu końców rozpoczyna się z ARR [0] i ARR [1] wyłącznie. Porównanie odbywa się z Pivot = i. Pierwsze i jedyne przystanki są na I i E: na ja dla ja i e za j. Teraz ja i J spotkałem lub skrzyżowałem. Tak więc podpisa pozostaje taka sama jak:

E i

Podział pod liście lub listę kończy. Tak więc nowe wartości dla ARR [i] i arr [high] są zamieniane. Zdarza się tutaj, że arr [i] = i i arr [high] = i. Tak więc ta sama wartość jest zamieniona na siebie. Nowa podpisa staje się:

E i

Jestem teraz na jego ostatecznej pozycji dla całej listy. Jego rola jako obrotu się zakończyła. Podpisa jest teraz podzielona na dwie kolejne listy, które są,

E i

Teraz, jak dotąd, są q, o i ja. Pivots kończą się na ich ostatecznych pozycjach. Podpisa pojedynczego elementu, takiego jak P powyżej, również kończy się w końcowej pozycji.

W tym momencie pierwsza lewa podrzędna została całkowicie posortowana. A procedura sortowania jest teraz w:

E i o p q y u r w t

Pierwsza właściwa podwodna:

Y u r w t

Nadal należy sortować.

Podbicie pierwszej prawej podrzędnej listy
Pamiętaj, że wywołanie szybkiego sortowania dla pierwszej prawej sub-listy zostało odnotowane i zastrzeżone zamiast zostać wykonane. W tym momencie zostanie wykonane. I tak, nowy ARR [niski] = arr [5] = arr [qpivotIndex+1], a nowy ARR [High] pozostaje ARR [9]. Podobny zestaw działań, które wydarzyły się dla pierwszej lewej podmiotów. I ta pierwsza prawa podpisa jest sortowana do:

R t u y

A oryginalna lista nieposortowana została sortowana do:

E i o p q r t u y

Kodowanie Java

Umieszczenie algorytmu w Javie to po prostu umieszczenie wszystkich powyższych segmentów pseudokodowych w metodach Java w jednej klasie. Nie zapominaj, że w klasie musi istnieć metoda main (), która wywoła funkcję Quicksort () z niepohamowaną tablicą.

Metoda Pivot ()

Metoda Java Pivot (), która zwraca wartość, obracanie, powinna być:

void Pivot (char arr [], int low, int high)
int mid = (niski + wysoki) / 2;
if (ARR [MID] < arr[low])
zamiana (ARR, niski, środkowy);
if (arr [high] < arr[low])
zamiana (ARR, niski, wysoki);
if ((high - niski)> 2)
if (ARR [MID] < arr[high])
zamiana (ARR, środkowa, wysoka);

Metoda swap ()

Metoda swap () powinna być:

void swap (char arr [], int x, int y)
char temp = arr [x];
arr [x] = arr [y];
arr [y] = temp;

Metoda Quicksort ()

Metoda Quicksort () powinna być:

void Quicksort (char arr [], int low, int high)
przepływam < high)
obrotowy (ARR, niski, wysoki);
int p = partycja (ARR, niska, wysoka);
Quicksort (ARR, Low, P - 1);
Quicksort (ARR, P + 1, High);

Metoda parition ()

Metoda parition () powinna być:

Int parition (char arr [], int low, int high)
char Pivot = arr [high];
int i = niski;
int j = high;
Do
Do
++I;
While (ARR [i] < pivot);
Do
--J;
while (ARR [J]> Pivot);
Jeśli ja < j)
swap (arr, i, j);
podczas gdy ja < j);
zamiana (arr, i, high);
powrót i;

Metoda główna ()

Metoda główna () może być:

public static void main (string [] args)
char arr [] = 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'i', ',', 'p';
Thlass quicksort = new theClass ();
Szybkie sortowanie.Quicksort (ARR, 0, 9);
System.na zewnątrz.println („posortowane elementy:”);
dla (int i = 0; i<10; i++)
System.na zewnątrz.print (ARR [i]); System.na zewnątrz.wydrukować(");

System.na zewnątrz.println ();

Wszystkie powyższe metody można umieścić w jednej klasie.

Wniosek

Szybkie sortowanie to algorytm sortowania, który wykorzystuje paradygmat podziału i koniunktury. Zaczyna się od podzielenia listy niepotrzebnej na dwie lub trzy pod liksy. W tym samouczku Quick Sort podzielił listę na trzy pod litera: lewa podwodna, środkowa lista pojedynczego elementu i prawą sub-listę. Podbój w szybkim sortowaniu dzieli listę lub podpisę podczas jej sortowania, używając wartości obrotowej. Ten samouczek wyjaśnił jedną wdrożenie szybkiego rodzaju w języku komputerowym Java.