Sortowanie przez wstawianie: Różnice pomiędzy wersjami

Z Wikipedii, wolnej encyklopedii
[wersja nieprzejrzana][wersja przejrzana]
Usunięta treść Dodana treść
Nie podano opisu zmian
Wandalizm - Wycofano ostatnią zmianę treści (wprowadzoną przez 83.30.30.9) i przywrócono wersję 39576680 autorstwa MalarzBOT
Linia 1: Linia 1:
{{Algorytm infobox
4

5

4

'''dsfgaerjn;atklmnhjiejn'''{{Algorytm infobox
|grafika=Insertion sort animation.gif
|grafika=Insertion sort animation.gif
|wielkość grafika=
|wielkość grafika=
Linia 14: Linia 8:
|pamiec=
|pamiec=
}}
}}
'''Sortowanie przez wstawianie''' (ang. ''InsuSort'', ''Insertion Sort'') - jeden z najprostszych [[algorytm]]ów [[sortowanie|sortowania]], którego zasada działania odzwierciedla sposób w jaki ludzie ustawiają karty - kolejne elementy wejś5o4uq4ewe są ustawiane na odpowiednie miejsca docelowe{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}. Jest efektywnry dla niewielkiej liczby elementów, jego [[złożoność obliczeniowa|złożoność]] wynosi [[Asymptotyczne tempo wzrostu|O(''n''<sup>2</sup>]]){{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}. Pomimo tego, że jest znaczni5u
'''Sortowanie przez wstawianie''' (ang. ''Insert Sort'', ''Insertion Sort'') - jeden z najprostszych [[algorytm]]ów [[sortowanie|sortowania]], którego zasada działania odzwierciedla sposób w jaki ludzie ustawiają karty - kolejne elementy wejściowe są ustawiane na odpowiednie miejsca docelowe{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}. Jest efektywny dla niewielkiej liczby elementów, jego [[złożoność obliczeniowa|złożoność]] wynosi [[Asymptotyczne tempo wzrostu|O(''n''<sup>2</sup>]]){{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}. Pomimo tego, że jest znacznie mniej wydajny od algorytmów takich jak [[Sortowanie szybkie|quicksort]] czy [[Sortowanie przez kopcowanie|heapsort]], posiada pewne zalety:
* danych wstępnie posortowanych{{fakt|data=2014-06}}
* jest wydajny dla danych wstępnie posortowanych{{fakt|data=2014-06}}
* jest wydajny dla zbiorów o niewielkiej liczebności{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}
* jest wydajny dla zbiorów o niewielkiej liczebności{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}
* jest stabilny{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}
* jest stabilny{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}


== Schemat działania algorytm uq==
== Schemat działania algorytmu {{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23}}==
[[Plik:Insertion-sort-example-300px.gif|right|Przykład działania]]
# 45wanych i przenieś do niego dowolny element ze zbioru nieposortowanego.
# Utwórz zbiór elementów posortowanych i przenieś do niego dowolny element ze zbioru nieposortowanego.
# Weź dowolny element ze zbioru nieposortowanego.
# Weź dowolny element ze zbioru nieposortowanego.
# Wyciągnięty element porównuj z kolejnymi elementrrami zbioru posortowanego póki nie napotkasz elementu równego lub elemenyu ększego (jeślri chcemy otrzymać ciąg niemalrwtejący) lub nie znajdziemy się na początku/końcu zbioruy uporządkowanego.
# Wyciągnięty element porównuj z kolejnymi elementami zbioru posortowanego póki nie napotkasz elementu równego lub elementu większego (jeśli chcemy otrzymać ciąg niemalejący) lub nie znajdziemy się na początku/końcu zbioru uporządkowanego.
# Wyciągnięty element wstaw w miejsce gdzie skończyłeś porównywać.
# Wyciągnięty element wstaw w miejsce gdzie skończyłeś porównywać.
# Jeśli zbiór elementów nieuporządkowanych jest niepusty wróć do punkt 2.
# Jeśli zbiór elementów nieuporządkowanych jest niepusty wróć do punkt 2.


== Algorytm - pseudo35kod ==
== Algorytm - pseudokod ==
Poniższy kod przedstawia algorytm zapisany w pseudokodzie, gdzie{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23-24}}:
Poniższy kod przedstawia algorytm zapisany w pseudokodzie, gdzie{{odn|Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein|s=23-24}}:
* A - tablica danych, p3yzenaczonych do posortowania (indeksowana od 1 do n)
* A - tablica danych, przeznaczonych do posortowania (indeksowana od 1 do n)
* n - liczba elementów wy tablicy A
* n - liczba elementów w tablicy A
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
0. Insert_sort(A, n)
0. Insert_sort(A, n)

Wersja z 22:40, 15 cze 2014

{{{nazwa}}}
Ilustracja
Rodzaj

Sortowanie

Struktura danych

Tablica, lista

Złożoność
Czasowa

O(n2)

Sortowanie przez wstawianie (ang. Insert Sort, Insertion Sort) - jeden z najprostszych algorytmów sortowania, którego zasada działania odzwierciedla sposób w jaki ludzie ustawiają karty - kolejne elementy wejściowe są ustawiane na odpowiednie miejsca docelowe[1]. Jest efektywny dla niewielkiej liczby elementów, jego złożoność wynosi O(n2)[1]. Pomimo tego, że jest znacznie mniej wydajny od algorytmów takich jak quicksort czy heapsort, posiada pewne zalety:

  • jest wydajny dla danych wstępnie posortowanych[potrzebny przypis]
  • jest wydajny dla zbiorów o niewielkiej liczebności[1]
  • jest stabilny[1]

Schemat działania algorytmu [1]

Przykład działania
Przykład działania
  1. Utwórz zbiór elementów posortowanych i przenieś do niego dowolny element ze zbioru nieposortowanego.
  2. Weź dowolny element ze zbioru nieposortowanego.
  3. Wyciągnięty element porównuj z kolejnymi elementami zbioru posortowanego póki nie napotkasz elementu równego lub elementu większego (jeśli chcemy otrzymać ciąg niemalejący) lub nie znajdziemy się na początku/końcu zbioru uporządkowanego.
  4. Wyciągnięty element wstaw w miejsce gdzie skończyłeś porównywać.
  5. Jeśli zbiór elementów nieuporządkowanych jest niepusty wróć do punkt 2.

Algorytm - pseudokod

Poniższy kod przedstawia algorytm zapisany w pseudokodzie, gdzie[2]:

  • A - tablica danych, przeznaczonych do posortowania (indeksowana od 1 do n)
  • n - liczba elementów w tablicy A
                                
0. Insert_sort(A, n)                     
1.    for i=2 to n :                                     
2.       klucz = A[i]
3        > Wstaw A[i] w posortowany ciąg A[1 ... i-1]                
4.       j = i - 1                                       
5.       while j>0 and A[j]>klucz:                       
6.          A[j + 1] = A[j]              
7.          j = j - 1                    
8.       A[j+1] = klucz

Analiza algorytmu [potrzebny przypis]

Złożoność

Niech δ(i) oznacza liczba sprawdzeń warunku pętli (4.) w i-tym przebiegu pętli (1.). Wtedy:

  • instrukcja 1. jest wykonana n razy
  • instrukcja 2. jest wykonana n-1 razy
  • instrukcja 3. jest wykonana n-1 razy (komentarz oznaczony przez >)
  • instrukcja 4. jest wykonana n-1 razy
  • instrukcja 5. jest wykonana razy
  • instrukcja 6. jest wykonana razy
  • instrukcja 7. jest wykonana razy
  • instrukcja 8. jest wykonana n-1 razy

Jeżeli przez c1, c2, ..., c8 oznaczymy czas pojedynczego wywołania instrukcji 1,2, ... 8, to całkowity czas wykonania algorytmu sortowania przez wstawianie będzie równy:

T(n) = c1n + (c2+c3+c4+c8)(n-1) + c5 + ()c6 + ()c7

Przypadek optymistyczny

Gdy tablica danych wejściowych jest uporządkowana rosnąco, to w każdym przebiegu pętli (1.) przy pierwszym sprawdzeniu warunków pętli (5.) zachodzi A[j]<klucz - pętla (5.) nie zostaje wykonana ani razu, a więc liczba sprawdzeń warunku pętli (5.) δ(i) wynosi 1 dla wszystkich j od 1 do n. Całkowity czas T(n) = (c1 + c2 + c4 + c5 + c8)n - (c2 + c4 + c5 + c8) wykonania algorytmu jest więc wyrażony funkcją liniową, z czego wynika, że dla posortowanych tablic o długości n algorytm insert sort działa w czasie O(n).

Przypadek pesymistyczny

Gdy tablica danych wejściowych jest uporządkowana malejąco, w każdym przebiegu pętli (1.) przy sprawdzaniu warunków pętli (5.) zachodzi A[j]>klucz - pętla (5.) w każdym i-tym przebiegu pętli (1.) jest wywoływana i-1 razy. Po podstawieniu do wzoru na T(n): δ(i) = i, otrzymuje się kwadratową złożoność czasową T(n) O(n2).

Przypadek średni

Przy założeniu, że wszystkie możliwe wartości tablicy A występują z jednakowym prawdopodobieństwem, można dowieść, że oczekiwana liczba elementów A[1..i] większych od wstawianego klucza wynosi i/2. W tym wypadku podstawienie δ(i) = i/2 daje podobnie jak w przypadku pesymistycznym złożoność T(n) O(n2).

Poprawność

Prawidłowość algorytmu sortowania przez wstawianie można dowieść, udowodniając poniższe twierdzenie:

w i-tym wykonaniu pętli for tablica A[1..i-1] składa się z posortowanych elementów znajdujących się w pierwotnej tablicy na pozycjach [1..i-1].

Dowód:

W pierwszej iteracji, dla i=1 zdanie jest prawdziwe (rozważamy posortowany ciąg A[1..1]).

W l-tej iteracji, jeżeli elementy A[1..l-2] są posortowane, to nowy klucz zostanie wstawiony na pozycję, w której nie będzie tworzył inwersji z żadnym z elementów w zbiorze do którego zostanie dołączony, a więc zbiór A[1..l-1] będzie posortowany.

W ostatniej iteracji pętli ostatni wolny klucz zostaje wstawiony w posortowany ciąg A[1..n-2] w wyniku czego powstaje posortowana tablica A[1..n-1]

Bezpośredni wniosek z powyższego twierdzenia: algorytm sortowania przez wstawianie dla każdej tablicy A dokona jej prawidłowego posortowania.

Przykłady implementacji

Wikiźródła Zobacz przykładowe implementacje sortowania przez wstawianie na Wikiźródłach

Zobacz też

Bibliografia

  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: Wprowadzenie do algorytmów. WNT, 2007.


Linki zewnętrzne