Copyright © 2014, Janusz Bonarowski 1
Ćwiczenie VB6.04 sortowanie
Zadanie
Zbudować aplikację, która zapełnia tablicę Dane (np. 10-cio elementową – Dane(9)) liczbami przypadkowymi całkowitymi z przedziału <0,20>. Posortować tablicę (1) algorytmem bąbelkowym i (2) algorytmem przez wybieranie.
Wypełnioną tablicę wyświetlać w ListBox1, a efekt sortowania w ListBox2.
Rysunek 1. Propozycja formularza Uwagi
• Aby wszystkie procedury miały dostęp do tabeli z danymi zadeklarujemy ją jako publiczną (tzn. na zewnątrz wszystkich procedur).
• Gdy zamierzamy zapełnić tabelę liczbami przypadkowymi rzeczywistymi z przedziału <min, max> stosujemy wzór:
min + (Rnd() * (max - min)),
• Gdy zamierzamy zapełnić tabelę liczbami przypadkowymi całkowitymi z przedziału <min, max>
stosujemy wzór:
Int(min + (Rnd() * (max - min + 1))).
W naszym przypadku generujemy, liczby przypadkowe całkowite z przedziału <0, 20> - wyrażenie zatem będzie miało postać:
Int((Rnd() * 21)).
• Oba sortowania wykonamy rosnąco (tzn. od najmniejszego do najwiekszego)
Sortowanie – algorytm bąbelkowy
Algorytm polega na wielokrotnym przeglądaniu elementów tablicy i porównywaniu parami dwóch kolejnych elementów, co możemy zapisać np. elementów Dane(j) i Dane(j+1).
Tabela będzie posortowana, gdy dla każdej wartości indeksu j będzie spełniony warunek:
Dane(j) < Dane(j+1).
Jeśli natomiast Dane(j) > Dane(j+1) - trzeba będzie je zamienić miejscami.
Zamianę miejscami wykonamy w 3 krokach, posługując się zmienną pomocniczą („chwilową”, ang. temporaty, stąd jej nazwa) tmp:
If Dane(j) > Dane(j + 1) Then tmp = Dane(j)
Dane(j) = Dane(j + 1) Dane(j + 1) = tmp End If
Copyright © 2014, Janusz Bonarowski 2
Sortowanie przez wybieranie
Algorytm ten ma następujący przebieg:
1. Poczynając od elementu i = 0 tabeli poszukujemy jej najmniejszego elementu.
2. Po znalezieniu najmniejszego elementu umieszczamy go w komórce tabeli o indeksie 0, a znajdujący się tam wcześniej element umieszczamy w tej komórce, gdzie był znaleziony element najmniejszy.
3. Następnie rozpoczynając od następnego elementu tabeli, czyli elementu i+1 szukamy w tabeli najmniejszego elementu i zamieniamy go z elementem na pozycji i+1
4. Powtarzamy szukanie i zamianę dla wszystkich elementów tabeli. Ale uwaga - ostatniego elementu nie ma potrzeby porównywać, a więc powtarzamy szukanie nie N ale N-1 razy.
Przykład
Niech tabela składa się z 4 elementów (stan I).
Poczynając od początku tabeli, czyli od elementu na pozycji (0), ma on wartość 9, poszukujemy
najmniejszego elementu w dół tabeli. Znajdujemy najmniejszy element na pozycji (1) ma on wartość 5.
Dokonujemy zamiany elementów na pozycjach (0) i (1). Tabela będzie zatem miała postać jak stan II.
Poczynając od następnego elementu, czyli od elementu na pozycji (1), który teraz ma wartość 9 poszukujemy najmniejszego elementu w dół tabeli. Okazuje się, że element na pozycji (3) o wartości 6 jest w tym podzbiorze elementem najmniejszym. Dokonujemy zamiany elementów na pozycjach (1) i (3).
Tabela będzie zatem miała postać jak stan III.
Poczynając od następnego elementu, czyli od elementu na pozycji (2), ma on wartość 8, poszukujemy najmniejszego elementu, w dół tabeli. Okazuje się, że najmniejszym elementem w tym podzbiorze jest właśnie element z pozycji (2) o wartości 8. Pozostawiamy tabelę bez zmiany, stan IV.
Ponieważ dokonaliśmy N-1 sprawdzeń kończymy algorytm. Tabela jest posortowana.
Postacie sortowanej tabeli
indeks stan I stan II Stan III Stan IV
(0) 9 5 5 5
(1) 5 9 6 6
(2) 8 8 8 8
(3) 6 6 9 9
Kod
For k = 0 To N - 1 Min = Dane(k) indexMin = k
For i = k + 1 To N
If Dane(i) < Min Then
'Zapamiętanie wartości minimalnej i jej indeksu Min = Dane(i)
indexMin = i End If
Next
'Zamiana miejscami tmp = Dane(indexMin) Dane(indexMin) = Dane(k) Dane(k) = tmp
Next
Copyright © 2014, Janusz Bonarowski 3
Kod aplikacji
Dim Dane(9) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Raz wywoływana funkcja zapewniająca "prawdziwą" przypadkowość generatora.
Randomize() End Sub
Private Sub btnGeneruj_Click(sender As Object, e As EventArgs) _
Handles btnGeneruj.Click 'Zapełnianie tablicy liczbami przypadkowymi
Dim i As Integer
For i = 0 To UBound(Dane) Dane(i) = Int(21 * Rnd()) Next
'Wydruk tabeli w ListBox1 ListBox1.Items.Clear() ListBox2.Items.Clear() For i = 0 To UBound(Dane)
ListBox1.Items.Add(CStr(Dane(i))) Next
End Sub
Private Sub btnSortBabelkowe_Click(sender As Object, e As EventArgs) _
Handles btnSortBabelkowe.Click 'Sortowanie bąbelkowe
'---
Dim i, j, tmp, N As Integer N = UBound(Dane)
For i = 0 To N
For j = 0 To (N - 1) - i 'N - 1 If Dane(j) > Dane(j + 1) Then
tmp = Dane(j)
Dane(j) = Dane(j + 1) Dane(j + 1) = tmp End If
Next Next
'Wydruk tabeli w ListBox1 ListBox2.Items.Clear() For i = 0 To UBound(Dane)
ListBox2.Items.Add(CStr(Dane(i))) Next
End Sub
Copyright © 2014, Janusz Bonarowski 4 Private Sub btnSortPrzezWybieranie_Click(sender As Object, e As EventArgs) _ Handles btnSortPrzezWybieranie.Click 'Sortowanie przez wybieranie
'---
Dim i, k, Min, tmp, indexMin, N As Integer N = UBound(Dane)
For k = 0 To N - 1 Min = Dane(k) indexMin = k
For i = k + 1 To N
If Dane(i) < Min Then Min = Dane(i) indexMin = i End If
Next
tmp = Dane(indexMin) ' lub tmp = Min Dane(indexMin) = Dane(k)
Dane(k) = tmp
'ListBox2.Items.Clear() 'For j = 0 To UBound(Dane)
' ListBox2.Items.Add(CStr(Dane(j))) 'Next
'MsgBox("Po przebiegu " & k, , "Liczba przebiegów " & N) Next
'Wydruk tabeli w ListBox2 ListBox2.Items.Clear() For i = 0 To UBound(Dane)
ListBox2.Items.Add(CStr(Dane(i))) Next
End Sub