QuickSort - liczba porównań i zamian

0

Witam, Chciałbym się dowiedzieć czy zarówno ten algorytm jak i wyniki są prawidłowe.

procedure quick(l,p : byte);
var
  i,j : integer;
  x,w: integer;
begin
   i:=l;
   j:=p;
   x:=tablica[(l+p) div 2];
   repeat
     while tablica[i] < x do begin i:=i+1; inc(licznikQ); end;
     while x < tablica[j] do begin j:=j-1; inc(licznikQ); end;
     if i <= j then
     begin
          w:=tablica[i];
          tablica[i]:=tablica[j];
          tablica[j]:=w;
          inc(zamienQ);
          i:=i+1;
          j:=j-1;
          inc(licznikQ);
     end;
   until i>j;
   if l < j then quick(l,j);
   if i < p then quick(i,p);
end;                               

Gdzie:
tablica[] jest tablicą z liczbami.
licznikQ - tutaj zapisywana jest liczba porównań
zamienQ - tutaj jest liczba przeprowadzonych zamian

I tak wyglądają przykładowe wyniki:
Tabela posortowana na wejściu:

Liczba elementów Porównania Zamiany
10 25 6
100 543 63
2000 1366 127
Tabela posortowana odwrotnie na wejściu:
Liczba elementów Porównania Zamiany
---------------- ---------------- ----------------
10 23 11
100 498 112
2000 1238 230
Losowe wartości na wejściu:
Liczba elementów Porównania Zamiany
---------------- ---------------- ----------------
10 26 10
100 738 186
2000 1692 428
0

Na początek może zajmij się pętlami while. N przebiegów pętli while to N + 1 sprawdzeń warunku, a ty liczysz tylko N porównań, czyli gubisz jedno za każdym razem.

0

W takim wypadku mam zamiast:

   while tablica[i] < x do begin i:=i+1; inc(licznikQ); end;
     while x < tablica[j] do begin j:=j-1; inc(licznikQ); end;

taki fragment:

     while tablica[i] < x do begin i:=i+1; inc(licznikQ); end;
     while x < tablica[j] do begin j:=j-1; inc(licznikQ); end;
     licznikQ:=licznikQ+2;  

I tak na przykład w przypadku 2000 liczb, wstępnie posortowanych odwrotnie mam wzrost liczby porównań do 1698 z 1238.

1

No OK.

A co ten ostatni inc(licznikQ) zlicza? Bo jeśli zlicza porównanie i <= j to na pewno nie powinien być w środku ifa. Z tym, że wydaje mi się, że w ogóle nie powinno go być, bo zliczasz głównie porównania między elementami, a nie indeksami - to, że elementy i indeksy mają tutaj taki sam typ nie ma żadnego znaczenia.

0

Dziękuję za wskazanie tego błędu. To niedopatrzenie, bo w tym ifie powinien zwiększać się jedynie licznik odnoszący się do ilości zamian.
A co do porównywania i oraz j to rzeczywiście nie powinno mieć tu wpływu. Dziękuję za pomoc. Taki prosty temat, ale mimo wszystko sprawia pewnego rodzaju trudności...

0

W sumie mam jeszcze dodatkowe uwagi:

  • jeśli i == j to może nie powinieneś liczyć zamiany? gdybyś nie liczył (i też nie robił bo nie ma sensu wtedy) w takim przypadku to liczba zamian w przypadku tablicy posortowanej na wejściu powinna wynieść 0,
  • w tabelkach zamiast 2000 chyba powinno być 200, no nie?
0

Co do pierwszej uwagi, to tak można zrobić, natomiast ja tutaj chcę porównać taką standardową wersję tego sortowania - "książkową". A w takiej wersji minusem jest właśnie ta złożoność przy posortowanej tablicy.
Co do drugiej uwagi, to powinno być 2000. Taką wartość dodałem, aby dla większej ilości danych sprawdzić wartości.

2

Co do drugiej uwagi, to powinno być 2000. Taką wartość dodałem, aby dla większej ilości danych sprawdzić wartości.

W takim razie to się zupełnie nie zgadza. Dla tablicy N-elementowej musi być co najmniej N-1 porównań, żeby stwierdzić posortowanie, a w QuickSorcie porównań będzie zwykle kilka razy więcej niż N. Podobnie z zamianami: posortowanie tablicy posortowanej odwrotnie wymagałoby co najmniej 1000 zamian w 2000-elementowej tablicy.

0

Udało mi się poprawić błąd, teraz w przypadku 2000 elementów w tablicy posortowanej odwrotnie mam ponad 20000 porównań (20018) oraz 2022 zamian. Natomiast w przypadku 2000 elementów w tablicy posortowanej normalnie mam 20010 porównań i 1023 zamiany.
A tablica wypełniona losowo to 28602 porównania i 2681 zamian.

1 użytkowników online, w tym zalogowanych: 0, gości: 1