|
Serwis Edukacyjny Nauczycieli w I-LO w Tarnowie
Materiały głownie dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
Algorytm sortowania przez wstawianie można porównać do sposobu układania kart pobieranych z talii. Najpierw bierzemy pierwszą kartę. Następnie pobieramy kolejne, aż do wyczerpania talii. Każdą pobraną kartę porównujemy z kartami, które już trzymamy w ręce i szukamy dla niej miejsca przed pierwszą kartą starszą (młodszą w przypadku porządku malejącego). Gdy znajdziemy takie miejsce, rozsuwamy karty i nową wstawiamy na przygotowane w ten sposób miejsce (stąd pochodzi nazwa algorytmu - sortowanie przez wstawianie, ang. Insertion Sort). Jeśli nasza karta jest najstarsza (najmłodsza), to umieszczamy ją na samym końcu. Tak porządkujemy karty. A jak przenieść tę ideę do świata komputerów i zbiorów liczbowych?
Algorytm sortowania przez wstawianie będzie składał się z dwóch pętli. Pętla główna (zewnętrzna) symuluje pobieranie kart, czyli w tym wypadku elementów zbioru. Odpowiednikiem kart na ręce jest tzw. lista uporządkowana (ang. sorted list), którą sukcesywnie będziemy tworzyli na końcu zbioru (istnieje też odmiana algorytmu umieszczająca listę uporządkowaną na początku zbioru). Pętla sortująca (wewnętrzna) szuka dla pobranego elementu miejsca na liście uporządkowanej. Jeśli takie miejsce zostanie znalezione, to elementy listy są odpowiednio rozsuwane, aby tworzyć miejsce na nowy element i element wybrany przez pętlę główną trafia tam. W ten sposób lista uporządkowana rozrasta się. Jeśli na liście uporządkowanej nie ma elementu większego od wybranego, to element ten trafia na koniec listy. Sortowanie zakończymy, gdy pętla główna wybierze wszystkie elementy zbioru.
Algorytm sortowania przez wstawianie posiada klasę czasowej złożoności obliczeniowej równą O(n2). Sortowanie odbywa się w miejscu.
Najważniejszą operacją w opisywanym algorytmie sortowania jest wstawianie wybranego elementu na listę uporządkowaną. Zasady są następujące:
Przykład:
Dla przykładu wstawmy wg opisanej metody pierwszy element zbioru listę uporządkowaną utworzoną z pozostałych elementów {8 4 5 6 9}. Elementy listy uporządkowanej zaznaczyliśmy kolorem zielonym. Puste miejsce zaznaczyliśmy kolorem białym:
| Zbiór | Opis operacji |
8 4 5 6 9
|
Element 8 znajduje się tuż przed listą uporządkowaną. |
8 4 5 6 9 |
Wybieramy ze zbioru element 8. Zajmowane przez niego miejsce staje się puste. |
8 4 5 6 9 |
Porównujemy 8 z pierwszym elementem listy uporządkowanej, z liczbą 4. |
8 4 <<< 5 6 9 |
Ponieważ element 4 jest mniejszy od elementu wybranego 8, przesuwamy go na puste miejsce. Zwróć uwagę, iż puste miejsce wędruje w kierunku końca listy uporządkowanej. |
8 4 5 6 9 |
Porównujemy 8 z kolejnym elementem listy uporządkowanej, z liczbą 5. |
8 4 5 <<< 6 9 |
5 jest5 mniejsze od 8, zatem wędruje na puste miejsce, które przesuwa się przed kolejny element listy uporządkowanej, liczbę 6. |
8 4 5 6 9 |
Porównujemy 8 z 6. |
8 4 5 6 <<< 9 |
6 jest mniejsze od 8, wędruje na puste miejsce. |
8 4 5 6 9 |
Porównujemy 8 z 9. |
4 5 6 8 9 |
Tym razem element wybrany wędruje na puste miejsce, ponieważ jest mniejszy od elementu 9 listy uporządkowanej. Operacja wstawiania jest zakończona. Lista rozrasta się o jeden element. |
Przykład:
Wykorzystajmy podane informacje do posortowania opisywaną metodą zbioru { 7 3 8 5 2 }.
| Zbiór | Opis operacji |
7 3 8 5 2
|
Ostatni element jest zalążkiem listy uporządkowanej. |
5 7 3 8 2 |
Ze zbioru wybieramy element leżący tuż przed listą uporządkowaną. |
5 7 3 8 2 |
Wybrany element porównujemy z elementem listy. |
5 7 3 8 2 <<< |
Ponieważ element listy jest mniejszy od elementu wybranego, to przesuwamy go na puste miejsce. |
7 3 8 2 5 |
Na liście nie ma już więcej elementów do porównania, więc element wybrany wstawiamy na puste miejsce. Lista uporządkowana zawiera już dwa elementy. |
8 7 3 2 5 |
Ze zbioru wybieramy 8 |
8 7 3 2 5 |
8 porównujemy z 2 |
8 7 3 2 <<< 5 |
2 jest mniejsze, zatem przesuwamy je na puste miejsce. |
8 7 3 2 5 |
8 porównujemy z 5 |
8 7 3 2 5 <<< |
5 jest mniejsze, przesuwamy je na puste miejsce |
7 3 2 5 8 |
Lista nie zawiera więcej elementów, zatem 8 wstawiamy na puste miejsce. Na liście uporządkowanej mamy już trzy elementy. |
3 7 2 5 8 |
Ze zbioru wybieramy 3 |
3 7 2 5 8 |
3 porównujemy z 2 |
3 7 2 <<< 5 8 |
2 jest mniejsze, wędruje zatem na puste miejsce |
3 7 2 5 8 |
3 porównujemy z 5. |
7 2 3 5 8 |
Tym razem mniejszy jest element wybrany. Znaleźliśmy jego miejsce na liście, więc wstawiamy go na puste miejsce. Lista zawiera już 4 elementy. |
7 2 3 5 8 |
Ze zbioru wybieramy ostatni element - liczbę 7. |
7 2 3 5 8 |
7 porównujemy z 2 |
7 2 <<< 3 5 8 |
2 jest mniejsze, przesuwamy je na puste miejsce |
7 2 3 5 8 |
7 porównujemy z 3 |
7 2 3 <<< 5 8 |
3 jest mniejsze, przesuwamy je na puste miejsce |
7 2 3 5 8 |
7 porównujemy z 5 |
7 2 3 5 <<< 8 |
5 jest mniejsze, przesuwamy je na puste miejsce |
7 2 3 5 8 |
7 porównujemy z 8 |
2 3 5 7 8 |
Element wybrany jest mniejszy, wstawiamy go na puste miejsce. Lista uporządkowana objęła już cały zbiór. Sortowanie jest zakończone. |
| n | - liczba elementów w sortowanym zbiorze, n ∈ N |
| d[ ] | - zbiór n-elementowy, który będzie sortowany. Elementy zbioru mają indeksy od 1 do n. |
| d[ ] | - posortowany zbiór n-elementowy. Elementy zbioru mają indeksy od 1 do n. |
| i, j | - zmienne sterujące pętli, i, j ∈ N |
| x | - zawiera wybrany ze zbioru element. |
| K01: | Dla j = n - 1,
n - 2, ..., 1: wykonuj kroki K02...K04 |
| K02: | x ← d[j]; i ← j + 1 |
| K03: | Dopóki ( i
≤
n ) ∧ ( x > d[i] ): wykonuj d[i - 1] ← d[i]; i ← i + 1 |
| K04: | d[i - 1] ← x |
| K05: | Zakończ |
Pętlę główną rozpoczynamy od przedostatniej pozycji w zbiorze. Element na ostatniej pozycji jest zalążkiem listy uporządkowanej. Dlatego licznik pętli nr 1 przyjmuje wartość początkową j = n - 1.
Ze zbioru wybieramy element d[j] i umieszczamy go w zmiennej pomocniczej x. Miejsce zajmowane przez ten element staje się puste.
| Uwaga techniczna
W rzeczywistości na pozycji j pozostaje dalej ten sam element. Jednakże zapamiętaliśmy jego wartość, zatem pozycja ta może być zapisana inną informacją - elementu nie utracimy, ponieważ przechowuje go zmienna x. Dlatego pozycję tę możemy potraktować jako pustą, tzn. z nieistotną zawartością. |
Pętlę wewnętrzną rozpoczynamy od pozycji następnej w stosunku do j. Pozycja ta zawiera pierwszy element listy uporządkowanej, która tworzona jest na końcu sortowanego zbioru. Pętlę wewnętrzną przerywamy w dwóch przypadkach - gdy licznik pętli wyjdzie poza indeks ostatniego elementu w zbiorze lub gdy element wybrany, przechowywany w zmiennej pomocniczej x, jest mniejszy lub równy bieżąco testowanemu elementowi listy uporządkowanej (dla sortowania malejącego należy zastosować w tym miejscu relację większy lub równy). W obu przypadkach na puste miejsce ma trafić zawartość zmiennej x i pętla zewnętrzna jest kontynuowana. Zauważ, iż pozycja tego miejsca w zbiorze jest równa i - 1.
Jeśli żaden z warunków przerwania pętli wewnętrznej nr 2 nie wystąpi, to przesuwamy bieżący element listy na puste miejsce i kontynuujemy pętlę wewnętrzną.
Podsumowując: pętla zewnętrzna wybiera ze zbioru kolejne elementy o indeksach od n - 1 do 1, pętla wewnętrzna szuka dla wybranych elementów miejsca wstawienia na liście uporządkowanej, po znalezieniu którego pętla zewnętrzna wstawia wybrany element na listę. Gdy pętla zewnętrzna przebiegnie wszystkie elementy o indeksach od n - 1 do 1, zbiór będzie posortowany.
Algorytm posiada klasę czasowej złożoności obliczeniowej równą O(n2). Sortowanie odbywa się w miejscu.
C++// Sortowanie Przez Wstawianie
//----------------------------
// (C)2012 mgr Jerzy Wałaszek
// I Liceum Ogólnokształcące
// im. K. Brodzińskiego
// w Tarnowie
#include <cmath>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <time.h>
using namespace std;
const int N = 20; // Liczebność zbioru.
// Program główny
//---------------
int main()
{
int d[N],i,j,x;
cout << " Sortowanie przez wstawianie\n"
"-----------------------------\n"
" (C)2005 Jerzy Walaszek\n\n"
"Przed sortowaniem:\n\n";
// Najpierw wypełniamy tablicę d[]
// liczbami pseudolosowymi, a następnie
// wyświetlamy jej zawartość
srand((unsigned)time(NULL));
for(i = 0; i < N; i++)
d[i] = rand() % 100;
for(i = 0; i < N; i++)
cout << setw(4) << d[i];
cout << endl << endl;
// Sortujemy
for(j = N - 2; j >= 0; j--)
{
x = d[j];
i = j + 1;
while((i < N) && (x > d[i]))
{
d[i - 1] = d[i];
i++;
}
d[i - 1] = x;
}
// Wyświetlamy wynik sortowania
cout << "Po sortowaniu:\n\n";
for(i = 0; i < N; i++)
cout << setw(4) << d[i];
cout << endl << endl;
system("pause");
return 0;
}
|
Pascal// Sortowanie Przez Wstawianie
//----------------------------
// (C)2012 mgr Jerzy Wałaszek
// I Liceum Ogólnokształcące
// im. K. Brodzińskiego
// w Tarnowie
program Insertion_Sort;
const N = 20; // Liczebność zbioru.
var
d : array[1..N] of integer;
// Program główny
//---------------
var
i,j,x : integer;
begin
writeln(' Sortowanie przez wstawianie ');
writeln('-----------------------------');
writeln(' (C)2005 Jerzy Walaszek ');
writeln;
// Najpierw wypełniamy tablicę d[]
// liczbami pseudolosowymi, a następnie
// wyświetlamy jej zawartość
randomize;
for i := 1 to N do
d[i] := random(100);
writeln('Przed sortowaniem:');
writeln;
for i := 1 to N do
write(d[i] : 4);
writeln;
writeln;
// Sortujemy
for j := N - 1 downto 1 do
begin
x := d[j];
i := j + 1;
while (i <= N) and (x > d[i]) do
begin
d[i - 1] := d[i];
inc(i);
end;
d[i - 1] := x;
end;
// Wyświetlamy wynik sortowania
writeln('Po sortowaniu:');
writeln;
for i := 1 to N do
write(d[i] : 4);
writeln;
writeln;
writeln('Nacisnij Enter...');
readln;
end.
|
Basic' Sortowanie Przez Wstawianie
'----------------------------
' (C)2012 mgr Jerzy Wałaszek
' I Liceum Ogólnokształcące
' im. K. Brodzińskiego
' w Tarnowie
CONST N = 20 ' Liczebność zbioru.
DIM AS INTEGER d(1 TO N),i,j,x
PRINT " Sortowanie przez wstawianie "
PRINT "-----------------------------"
PRINT " (C)2005 Jerzy Walaszek "
PRINT
' Najpierw wypełniamy tablicę d()
' liczbami pseudolosowymi, a następnie
' wyświetlamy jej zawartość
RANDOMIZE TIMER
FOR i = 1 TO N
d(i) = INT(RND * 100)
NEXT
PRINT "Przed sortowaniem:"
PRINT
FOR i = 1 TO N
PRINT USING "####"; d(i);
NEXT
PRINT
PRINT
' Sortujemy
FOR j = N - 1 TO 1 STEP -1
x = d(j)
i = j + 1
WHILE (i <= N) AND (x > d(i))
d(i - 1) = d(i)
i += 1
WEND
d(i - 1) = x
NEXT
' Wyświetlamy wynik sortowania
PRINT "Po sortowaniu:"
PRINT
FOR i = 1 TO N
PRINT USING "####"; d(i);
NEXT
PRINT
PRINT
PRINT "Nacisnij Enter..."
SLEEP
END
|
Python
(dodatek)# Sortowanie Przez Wstawianie
#----------------------------
# (C)2012 mgr Jerzy Wałaszek
# I Liceum Ogólnokształcące
# im. K. Brodzińskiego
# w Tarnowie
import random
n = 20 # Liczebność zbioru.
d = [random.randrange(100) for i in range(n)]
print(" Sortowanie przez wstawianie ")
print("-----------------------------")
print(" (C)2026 Jerzy Walaszek")
print()
# Wyświetlamy d[]
print("Przed sortowaniem:")
print()
for i in range(n):
print("%4d" % (d[i]),end="")
print()
print()
# Sortujemy
for j in reversed(range(n)):
x = d[j]
i = j + 1
while (i < n) and (x > d[i]):
d[i - 1] = d[i]
i += 1
d[i - 1] = x
# Wyświetlamy wynik sortowania
print("Po sortowaniu:")
print()
for i in range(n):
print("%4d" % (d[i]),end="")
print()
print()
input("Naciśnij Enter...")
|
| Wynik: |
Sortowanie przez wstawianie ----------------------------- (C)2026 Jerzy Walaszek Przed sortowaniem: 1 83 70 21 5 22 16 60 21 94 68 15 82 85 77 20 43 80 40 51 Po sortowaniu: 1 5 15 16 20 21 21 22 40 43 51 60 68 70 77 80 82 83 85 94 Naciśnij Enter... |
JavaScript<html>
<head>
</head>
<body>
<div style="overflow-x: auto;"
align="center">
<table
border="0"
cellpadding="4"
style="border-collapse:
collapse">
<tr>
<td nowrap>
<form
name="frm"
style="text-align:
center;
background-color:
#E7E7DA">
<b>
Sortowanie Przez
Wstawianie
</b><br/>
(C)2026 mgr
Jerzy Wałaszek
<hr/>
<input
onclick="main()"
value="Sortuj"
name="B2"
type="button">
<hr/>
<div id="out">.</div>
</form>
</td>
</tr>
</table>
</div>
<script language="javascript">
// Sortowanie Przez Wstawianie
//----------------------------
// (C)2005 mgr Jerzy Wałaszek
// I Liceum Ogólnokształcące
// im. K. Brodzińskiego
// w Tarnowie
var N = 20;
function main()
{
var d = new Array(N);
var i,j,x,t;
// Najpierw wypełniamy
// tablicę d[] liczbami
// pseudolosowymi
for(i = 0; i < N; i++)
d[i] = Math.floor(
Math.random() *
100);
t = "Przed sortowaniem:" +
"<br/><br/>";
for(i = 0; i < N; i++)
t += d[i] + " ";
t += "<br/><br/>";
// Sortujemy
for(j = N - 2; j >= 0; j--)
{
x = d[j];
i = j + 1;
while((i < N) &&
(x > d[i]))
{
d[i - 1] = d[i];
i++;
}
d[i - 1] = x;
}
// Wyświetlamy wynik
// sortowania
t += "Po sortowaniu:" +
"<br/><br/>";
for(i = 0; i < N; i++)
t += d[i] + " ";
document.getElementById("out")
.innerHTML = t;
}
</script>
</body>
</html> |
| Cechy Algorytmu Sortowania Przez Wstawianie | |
| klasa złożoności obliczeniowej optymistyczna | O(n) |
| klasa złożoności obliczeniowej typowa | O(n2) |
| klasa złożoności obliczeniowej pesymistyczna | O(n2) |
| Sortowanie w miejscu | TAK |
| Stabilność | TAK |
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.