R12192efrJ5bH
Grafika przedstawia dwa splecione symbole węży. Jeden jest niebieski, a drugi żółty.

Porządkowanie w Pythonie

Logo języka Python
Źródło: Dnu72, dostępny w internecie: commons.wikimedia.org, licencja: CC BY-SA 4.0.

Z porządkowaniem spotykamy się każdego dnia. Porządkujemy rzeczy i nawet nie zastanawiamy się, jak to robimy, np. układając w szufladzie kolejne miseczki, umieszczając mniejszą w większej, a tę większą następnie w jeszcze większej itd.

Również systemy informatyczne wykorzystują często tę operację – nazywamy ją sortowaniem. Posortowana jest np. lista kontaktów w telefonie – niezależnie od tego, w jakiej kolejności dodawaliśmy kontakty, możemy wyświetlać je posortowane alfabetycznie (sortowanie zgodnie z porządkiem liter alfabetu nazywamy porządkiem leksykograficznym).

Dużo łatwiej jest nam korzystać z danych uporządkowanych. Komputery do sortowania danych używają różnych algorytmów. W tym materiale zapoznamy się z algorytmem porządkowania metodą przez wybieranie.

Porządkujemy karty

Dana jest talia 24 kart, w której hierarchia kart przedstawia się następująco: 9, 10, W, D, K, A (dziewiątka, dziesiątka, walet, dama, król, as). Przyjmijmy, że po rozdaniu mamy w ręce kilka nieuporządkowanych kart. Chcemy uporządkować je od najmłodszej (o najmniejszej wartości) do najstarszej (o największej wartości), czyli niemalejąco. Możemy przyjąć następującą strategię:

  1. Szukamy najmniejszej karty i zamieniamy ją z kartą pierwszą.

  2. Spośród pozostałych kart wybieramy najmniejszą i zamieniamy z kartą drugą.

  3. Kroki 1 oraz 2 powtarzamy dla wszystkich kart. Po ich wykonaniu karty są posortowane.

Przeanalizujmy przykład.

Przykład 1

Przeanalizujmy porządkowanie kart niemalejąco za pomocą algorytmu sortowania przez wybieranie.

Pogrubienie w kolumnie „Karty” oznacza elementy uporządkowane.

Numer
zamiany

Karty

Najmniejsza karta

Operacja

1

A W 10 D K

10

zamiana A z 10

2

10 W A D K

W

brak zamiany, W jest na właściwym miejscu

3

10 W A D K

D

zamiana A z D

4

10 W D A K

K

zamiana A z K

-

10 W D K A

-

karty zostały uporządkowane

Liczba elementów do uporządkowania: 5

Liczba powtórzeń: 4

Ważne!

Podczas sortowania z wykorzystaniem algorytmu przez wybieranie porządkowane dane dzielą się na dwie części: uporządkowaną i nieuporządkowaną. Wyszukiwanie najmniejszego albo największego (zależnie od przyjętych założeń) elementu odbywa się zawsze w części nieuporządkowanej, a znaleziony element dołączany jest do części uporządkowanej. Kiedy w części nieuporządkowanej pozostaje jeden element, algorytm kończy działanie.

Algorytm porządkowania metodą przez wybieranie

Napiszemy program, który uporządkuje w sposób niemalejący wyniki konkursu. Wykorzystamy algorytm porządkowania metodą przez wybieranie.

Dane wejściowe:

  • n – liczba naturalna, liczba elementów listy

  • wyniki – lista zawierająca nieuporządkowane liczby naturalne z przedziału <1; 50>.

Wynik:

  • wyniki – lista zawierająca uporządkowane niemalejąco liczby naturalne

Zmienne pomocnicze:

  • i, j, k – liczby naturalne, indeksy porównywanych elementów listy

Zapiszemy algorytm w postaci listy kroków.

  1. Wczytaj wartość zmiennej n.

  2. Do listy wyniki wczytaj n wyników.

  3. Do zmiennej i przypisz 0.

  4. Dopóki i jest mniejsze od n - 1, wykonuj:

    4.1. Do zmiennej k przypisz wartość zmiennej i.

    4.2. Do zmiennej j przypisz i + 1.

    4.3. Dopóki j jest mniejsze od n, wykonuj:

    4.3.1. Jeżeli liczba wyniki[j] jest mniejsza od liczby wyniki[k], do zmiennej k przypisz wartość zmiennej j.

    4.3.2. Zwiększ wartość zmiennej j o 1.

    4.4. Zamień ze sobą wartości wyniki[i]wyniki[k].

    4.5. Zwiększ i o 1.

  5. Wypisz wartość zmiennej wyniki.

W kroku 1 i 2 przygotowujemy dane wejściowe.

Właściwy algorytm porządkowania wymaga dwóch pętli.

Pętla zewnętrzna

W kroku 4 konstruujemy pętlę zewnętrzną, która wykonuje się n - 1 razy, ponieważ, jak wynika z podanych przykładów, tyle trzeba wykonać operacji wyszukiwania elementu najmniejszego (albo największego). W omawianej pętli korzystamy ze zmiennej iteracyjnejzmienna iteracyjnazmiennej iteracyjnej i, która przyjmuje wartości od 0 do n - 1.

Wyszukiwanie elementu najmniejszego

Wyszukiwanie najmniejszego elementu rozpoczynamy od zainicjowania jego indeksu, czyli zmiennej pomocniczejzmienna pomocniczazmiennej pomocniczej k. Na początku każdego powtórzenia przypisujemy do niego i, tzn. indeks pierwszego nieuporządkowanego elementu listy.

pętli wewnętrznejpętle zagnieżdżonepętli wewnętrznej zapisanej w krokach 4.2 i 4.3, odczytujemy kolejne nieuporządkowane elementy wskazywane za pomocą indeksu j, który przyjmuje wartości od i + 1 do n - 1. Jeżeli dla któregoś z elementów warunek wyniki[j] < wyniki[k] będzie prawdziwy, aktualizujemy indeks najmniejszego elementu: k = j.

Zamiana elementów

Po zakończeniu pętli wewnętrznej indeks najmniejszego elementu zapisany jest w zmiennej k. Są dwie możliwości:

  • wśród nieuporządkowanych elementów nie ma mniejszego i wartość k pozostaje równa i, co oznacza, że kolejny element jest już na właściwym miejscu,

  • znaleźliśmy mniejszy element wśród nieuporządkowanych elementów i wartość zmiennej k uległa zmianie.

By uprościć budowę algorytmu, wykonujemy zamianę elementów o indeksach i oraz k, nawet jeżeli są równe. Operację tę wykonujemy w kroku 4.4.

Zapoznajmy się z przykładem, który pozwoli lepiej zrozumieć działania wykonywane w pętlach.

Przykład 2

Przeanalizujmy, w jaki sposób działa porządkowanie liczb w sposób niemalejący za pomocą algorytmu wykorzystującego wybieranie.

Pogrubienie w kolumnie Sortowane liczby oznacza elementy uporządkowane.

Powtórzenie

Sortowane liczby

Najmniejsza liczba

Zmienne i operacja

1

1 4 9 7 2 1

1

i = 0, k = 0,
1 jest na właściwym miejscu

2

1 4 9 7 2 1

1

i = 1, k = 5,
zamiana 4 z 1

3

1 1 9 7 2 4

2

i = 2, k = 4,
zamiana 9 z 2

4

1 1 2 7 9 4

4

i = 3, k = 5,
zamiana 7 z 4

5

1 1 2 4 9 7

7

i = 4k = 5zamiana 9 z 7

-

1 1 2 4 7 9

-

liczby zostały uporządkowane

Liczba elementów do uporządkowania: 6

Liczba powtórzeń: 5

Po zakończeniu pętli wewnętrznej indeks najmniejszego elementu jest przechowywany w zmiennej k (k = 5).

Zapis algorytmu za pomocą języka Python

Do pisania programu użyj dostępnego w swoim środowisku edytora, np. IDLE dołączonego do standardowej instalacji języka Python.

Przykład 3

Skopiuj kod, wklej go do pustego pliku i zapisz pod nazwą sort_wybieranie.py.

Linia 1. n znak równości 10. Linia 2. wyniki znak równości otwórz nawias kwadratowy 24 przecinek 14 przecinek 34 przecinek 11 przecinek 50 przecinek 39 przecinek 44 przecinek 15 przecinek 45 przecinek 15 zamknij nawias kwadratowy. Linia 3. print otwórz nawias okrągły asterysk wyniki zamknij nawias okrągły.

W instrukcji print() używamy symbolu * (gwiazdka), aby w terminalu wypisane zostały wartości z listy, tzn. oddzielone spacjami, bez dodatkowych znaków (nawiasów kwadratowych oraz przecinków) służących do zapisu listy.

Pętle

Zacznijmy od zapisania pętli zewnętrznej i zainicjowania indeksu najmniejszego elementu.

Polecenie 1

W pliku sort_wybieranie.py wstaw kod pętli zewnętrznej (krok 3 i 4), która korzysta ze zmiennej iteracyjnej i oraz wykonuje się n - 1 razy. Użyj instrukcji for i in range().

W ciele pętli zainicjuj zmienną k wartością i.

Zapiszmy pętlę wewnętrzną.

Polecenie 2

W pliku sort_wybieranie.py w pętli zewnętrznej po instrukcji inicjującej zmienną k dodaj pętlę (kroki 4.2, 4.3), która wykorzystuje zmienną j przyjmującą wartości z zakresu <i + 1, n - 1>. Użyj instrukcji for i in range().

Wewnątrz pętli umieść instrukcję warunkową wyniki[j] < wyniki[k].

Jeśli warunek jest prawdziwy, powinna zostać wykonana operacja przypisania k = j. Użyj instrukcji if.

Pozostaje zapisanie operacji zamiany wartości elementów o indeksach k oraz i, a następnie wypisanie wyniku.

Polecenie 3

W pliku sort_wybieranie.py wstaw podane instrukcje:

Linia 1. kratka zamiana wartości. Linia 2. wyniki otwórz nawias kwadratowy i zamknij nawias kwadratowy przecinek wyniki otwórz nawias kwadratowy k zamknij nawias kwadratowy znak równości wyniki otwórz nawias kwadratowy k zamknij nawias kwadratowy przecinek wyniki otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 4. kratka wypisanie posortowanej listy. Linia 5. print otwórz nawias okrągły asterysk wyniki zamknij nawias okrągły.

Użyty sposób zamiany wartości jest przykładem możliwego w języku Python przypisania wielokrotnego. W przypadku tej konstrukcji do zmiennych z lewej strony przypisywane są wartości kolejnych zmiennych z prawej strony. Są to początkowe wartości tych zmiennych. Dzięki temu możemy zamienić wartości dwóch elementów.

Ciekawostka

Innym sposobem zamiany wartości, który można stosować we wszystkich językach programowania, jest użycie zmiennej pomocniczej, w której zapamiętujemy jedną z zamienianych wartości:

Linia 1. kratka zamiana liczb. Linia 2. tmp znak równości wyniki otwórz nawias kwadratowy i zamknij nawias kwadratowy kratka użycie dodatkowej zmiennej tymczasowej do przechowania wartości. Linia 3. wyniki otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości wyniki otwórz nawias kwadratowy k zamknij nawias kwadratowy. Linia 4. wyniki otwórz nawias kwadratowy k zamknij nawias kwadratowy znak równości tmp.

Żeby zrozumieć konieczność użycia zmiennej pomocniczej, weźmy dla przykładu listę z dwoma wartościami: liczby = [4, 7]. Pierwsza wartość ma indeks 0, druga 1. Prześledźmy co się stanie, kiedy nie użyjemy zmiennej pomocniczej:

Linia 1. liczby otwórz nawias kwadratowy 0 zamknij nawias kwadratowy znak równości liczby otwórz nawias kwadratowy 1 zamknij nawias kwadratowy.

Po wykonaniu tej operacji lista ma postać: [7, 7]. Na pozycji 0 znalazła się wartość 7 spod indeksu 1. Wartość 4 została nadpisana.

Wykonajmy kolejną operację:

Linia 1. liczby otwórz nawias kwadratowy 1 zamknij nawias kwadratowy znak równości liczby otwórz nawias kwadratowy 0 zamknij nawias kwadratowy.

Zawartość listy się nie zmienia, ponieważ na obu pozycjach jest ta sama wartość, czyli 7.

Przetestujmy działanie programu.

Polecenie 4

Uruchom program sort_wybieranie.py.

Notatnik

RpBWipTIzEZtS
Miejsce na Twoje notatki: (Uzupełnij) .

Animacja (samouczek)

Film przedstawia program wykorzystujący algorytm porządkowania przez wybieranie. Wypisuje znaki z pobranego napisu w porządku alfabetycznym (leksykograficznym), np. dla słowa czara powinniśmy otrzymać ciąg znaków a a c r z.

RRs30Jc8FiQa5
Film przedstawia algorytm sortowania metodą porządkowania

Pełny kod programu:

Linia 1. napis znak równości input otwórz nawias okrągły cudzysłów Podaj ciąg znaków dwukropek cudzysłów zamknij nawias okrągły. Linia 2. napis znak równości napis kropka lower otwórz nawias okrągły zamknij nawias okrągły kropka replace otwórz nawias okrągły cudzysłów cudzysłów przecinek cudzysłów cudzysłów zamknij nawias okrągły. Linia 4. napis znak równości list otwórz nawias okrągły napis zamknij nawias okrągły kratka Funkcja list otwórz nawias okrągły zamknij nawias okrągły zamienia napis na listę. Linia 5. n znak równości len otwórz nawias okrągły napis zamknij nawias okrągły kratka Funkcja len otwórz nawias okrągły zamknij nawias okrągły zwraca liczbę znaków otwórz nawias okrągły długość łańcucha znaków zamknij nawias okrągły. Linia 6. print otwórz nawias okrągły cudzysłów Lista znaków dwukropek cudzysłów przecinek napis zamknij nawias okrągły. Linia 7. print otwórz nawias okrągły cudzysłów Liczba znaków dwukropek cudzysłów przecinek n zamknij nawias okrągły. Linia 9. for i in range otwórz nawias okrągły n minus 1 zamknij nawias okrągły dwukropek. Linia 10. k znak równości i. Linia 11. for j in range otwórz nawias okrągły i plus 1 przecinek n zamknij nawias okrągły dwukropek. Linia 12. if napis otwórz nawias kwadratowy k zamknij nawias kwadratowy zamknij nawias ostrokątny napis otwórz nawias kwadratowy j zamknij nawias kwadratowy dwukropek. Linia 13. k znak równości j. Linia 14. print otwórz nawias okrągły cudzysłów Powtórzenie dwukropek cudzysłów przecinek i plus 1 zamknij nawias okrągły. Linia 15. print otwórz nawias okrągły asterysk napis zamknij nawias okrągły. Linia 16. print otwórz nawias okrągły cudzysłów i znak równości cudzysłów przecinek i przecinek cudzysłów k znak równości cudzysłów przecinek k przecinek cudzysłów zamiana dwukropek cudzysłów przecinek napis otwórz nawias kwadratowy i zamknij nawias kwadratowy przecinek cudzysłów z cudzysłów przecinek napis otwórz nawias kwadratowy k zamknij nawias kwadratowy zamknij nawias okrągły. Linia 17. print otwórz nawias okrągły zamknij nawias okrągły. Linia 18. napis otwórz nawias kwadratowy i zamknij nawias kwadratowy przecinek napis otwórz nawias kwadratowy k zamknij nawias kwadratowy znak równości napis otwórz nawias kwadratowy k zamknij nawias kwadratowy przecinek napis otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 20. print otwórz nawias okrągły asterysk napis zamknij nawias okrągły.
Polecenie 5
R4DC5Rd9nEdCQ
Dokończ zdanie: Instrukcja napis = list(napis) zamienia ciąg znaków na listę, aby można było...
Źródło: Robert Bednarz, licencja: CC BY 3.0.
1
Polecenie 6

Uruchom program sortuj_napis.py, podając napis: 675431. Ile niepotrzebnych zamian znaków wykona algorytm? Przez niepotrzebną zamianę rozumiemy przypadek, kiedy znak jest już na swoim miejscu.

Wskazówka: Zwróć uwagę na wypisane komunikaty. Ile razy zmienne i oraz k są sobie równe?

Polecenie 7

Zmień program sortuj_napis.py w taki sposób, żeby porządkował podane znaki w sposób nierosnący. Przetestuj działanie programu dla napisów: testtesty. Ile było niepotrzebnych zamian znaków?

Wskazówka: Aby zmienić porządek sortowania, należy wprowadzić zmianę w kodzie instrukcji warunkowej.

Zestaw ćwiczeń interaktywnych

R12HktlZajl1b
Ćwiczenie 1
Zaznacz poprawną odpowiedź.
Jeżeli mamy n elementów do posortowania metodą przez wybieranie, to liczba powtórzeń operacji wybierania najmniejszego/największego elementu wyniesie: Możliwe odpowiedzi: 1. n - 1, 2. n, 3. n + 1
Źródło: Robert Bednarz, licencja: CC BY 3.0.
Ćwiczenie 2

Zapoznaj się z fragmentem kodu i wykonaj ćwiczenie.

Linia 1. zmienna podkreślnik pomocnicza znak równości zmienna podkreślnik a. Linia 2. XXX znak równości YYY. Linia 3. YYY znak równości zmienna podkreślnik pomocnicza.
RjQTzwYigM5vt
Zaznacz wszystkie poprawne odpowiedzi.
Do zakodowania algorytmu porządkowania metodą przez wybieranie użyjesz: Możliwe odpowiedzi: 1. instrukcji pobierania, 2. pętli while, 3. pętli for, 4. instrukcji warunkowej, 5. operacji zamiany wartości
Źródło: Robert Bednarz, licencja: CC BY 3.0.
R1eu4zCzoz43K
Ćwiczenie 3
Ułóż we właściwej kolejności podane instrukcje, tak aby sortowały listę przy użyciu algorytmu porządkowania metodą przez wybieranie. Elementy do uszeregowania: 1. for j in range(i+1, n):, 2. for i in range(n-1), 3. wyniki[i], wyniki[k] = wyniki[k], wyniki[i], 4. k = j, 5. if wyniki[j] < wyniki[k]:, 6. k = i
Źródło: Robert Bednarz, licencja: CC BY 3.0.
RPFTSAUxSJ4JR
Ćwiczenie 4
Zaznacz poprawną odpowiedź.
Zadaniem pętli wewnętrznej w algorytmie porządkowania metodą przez wybieranie jest: Możliwe odpowiedzi: 1. wyszukiwanie najmniejszego / największego elementu wśród elementów nieuporządkowanych, 2. zamiana wartości elementów, 3. wyszukiwanie najmniejszego / największego elementu wśród wszystkich elementów, 4. pobieranie elementów
Źródło: Robert Bednarz, licencja: CC BY 3.0.
R2ZpLMwHgtgHN
Ćwiczenie 5
Zaznacz poprawną odpowiedź
W wyniku wykonania instrukcji a, b = b, a: Możliwe odpowiedzi: 1. wartości zmiennych ab zostaną zamienione, 2. wartości zmiennych ab zostaną podwojone, 3. otrzymamy wartość True lub False, 4. zostanie wyświetlony błąd składni
Źródło: Robert Bednarz, licencja: CC BY 3.0.
RwSA3C1HCkxJM
Ćwiczenie 6
Nagłówek tabeli zawiera nieuporządkowaną listę liczb. Numery wierszy oznaczają kolejne kroki ich porządkowania. W pustych komórkach każdego wiersza wpisz liczby w takiej kolejności, w jakiej są porządkowane w kolejnych krokach sortowania niemalejącego przy użyciu metody przez wybieranie.
Źródło: Robert Bednarz, licencja: CC BY 3.0.
11
Ćwiczenie 7

Ćwiczenie wykonaj, korzystając z testerki.

RqJBpnqyylx281
11
Ćwiczenie 8

Ćwiczenie wykonaj, korzystając z testerki.

R11ydxjiD49fK1

Słownik

pętle zagnieżdżone
pętle zagnieżdżone

pętle, które zostały zamieszczone wewnątrz innych pętli; dla każdego powtórzenia pętli zewnętrznej wykonywane są wszystkie powtórzenia pętli wewnętrznej

zmienna iteracyjna
zmienna iteracyjna

zmienna kontrolująca działanie pętli; w języku Python w każdym powtórzeniu przyjmuje kolejne wartości ze zdefiniowanego zakresu

zmienna pomocnicza
zmienna pomocnicza

zmienna tymczasowo przechowująca pośredni wynik obliczeń lub daną wartość