
5. Сортування масиву.
Сортування масиву – це упорядковування його елементів. Упорядковування може відбуватись у двох напрямках: упорядковування у напрямку зростання елементів та упорядковування у напрямку спадання, тобто у першому випадку сортування перетворить масив на зростаючу послідовниість елементів, у другому – у спадну. Сортувати можна як одновимірні масиви, так і двовимірні.
Існує кілька видів сортування. Ми розглянемо 2 з них: сортування методом обміну та сортування методом прямого вибору.
Сортування методом обміну.
Нехай дано одновимірний масив з 5 чисел: 2, 6, 8, 1, 4. Необхідно впорядкувати елементи цього масиву за зростанням.
Сутність даного методу полягатиме в слідуючому: кожний елемент Х масиву порівнюється з елементом Y, який стоіть справа від нього, і якщо елемент Х виявиться більшим за Y, то Х міняється з Y місцями. Таким чином, менший елемент переміщується вліво у масиві, а більший – вправо, що дає змогу за певну кількість таких обмінів розташувати елементи від найменшого до найбільшого.
Розглянемо все сказане на нашому масиві.
Вхідний масив: 2 6 8 1 4.
1 етап. Виконаємо порівняння 1-го елемента масива з усіма елементами, які знаходяться у масиві справа від нього.
1 крок. 1-й елемент порівнюємо з 2-м: 2 < 6. Отже, на цому крокові обмін не потрібний.
2 крок. 2-й елемент порівнюємо з 3-м: 6 < 8. Отже, на цому крокові обмін не потрібний.
3 крок. 3-й елемент порівнюємо з 4-м: 8 > 1. Виконується обмін цих елементів. Новий вигляд масиву: 2 6 1 8 4.
4 крок. 4-й елемент порівнюємо з 5-м : 8 > 4. Виконується обмін цих елементів. Новий вигляд масиву: 2 6 1 4 8.
Таким чином, на 1 етапі було зроблено 4 кроки, тобто на 1 менше, ніж елементів у масиву.
2 етап. Знову виконуємо порівняння кожного елементу масиву з елементом, що стоіть справа від нього.
1 крок. 1-й елемент порівнюємо з 2-м: 2 < 6. Отже, на цому крокові обмін не потрібний.
2 крок. 2-й елемент порівнюємо з 3-м: 6 > 1. Виконується обмін цих елементів. Новий вигляд масиву: 2 1 6 4 8.
3 крок. 3-й елемент порівнюємо з 4-м: 6 > 4. Виконується обмін цих елементів. Новий вигляд масиву: 2 1 4 6 8.
4 крок. 4-й елемент порівнюємо з 5-м: 6 < 8. Отже, на цому крокові обмін не потрібний.
Таким чином, на 2етапі теж було виконано 4 кроки.
Аналогічно виконуються інші етапи сортування, причому максимально необхідна кількість етапів сортування для даного масиву – 4, тобто на 1 менше, ніж елементів масиву.
Отже, для сортування 5 елементів виявилися необхідними не більше, ніж 4 етапи (тобто на 1менше, ніж елементів у масиві), на кожному з яких знадобилося виконати 4 кроки (тобто кількість кроків є на 1 меншою, ніж елементів у масиві). Ця інформація знадобиться нам при складанні програми.
Якщо сортируємо масив за спаданням елементів, все відбувається так само, тільки обмін відбувається, якщо елемент Х виявиться меншим за Y.
Яким же чином реалізується обмін двох елментів масиву під час сортування у межах Object Pascal? Нехай необхідно поміняти місцями елемент Х і елемент Y. Введемо додаткову (буферну) змінну B. Тоді значення змінної Х запишемо у буферну змінну В, на місце змінної Х запишемо значення змінної Y, а на місце змінної Y – значення буферної змінної В.
2
Х
Y
1 3
B
Таким чином, коли ми записуємо значення Y в Х, ми знищуємо значення Х, але воно вже збережене у змінній В. Аналогічно, коли записуємо В у Y, Y знищується, але вого вже збережене у Х.
Реалізуємо даний метод сортування при складанні програми.
Задача 1. Відсортувати за зростанням методом обміну масив з 7 цілих чисел.
Розв’язування.
Перелік використаних компонентів та їх властивості:
Компонент |
Властивість |
Значення |
Form1 |
Caption |
Сортування методом обміну |
Label1 |
Caption |
Вхідний масив: |
StringGrid1 |
FixedCols |
0 |
StringGrid1 |
FixedRows |
1 |
StringGrid1 |
ColCount |
7 |
StringGrid1 |
RowCount |
2 |
StringGrid1 |
Options.goTabs |
true |
StringGrid1 |
Options.goEditing |
true |
Button1 |
Caption |
Сортування |
Label2 |
Caption |
Відсортований масив: |
StringGrid1 |
FixedCols |
0 |
StringGrid1 |
FixedRows |
1 |
StringGrid1 |
ColCount |
7 |
StringGrid1 |
RowCount |
2 |
Button2 |
Caption |
Новий розв'язок |
Button3 |
Caption |
Вихід |
Вигляд форми з поміщеними на ній компонентами:
Текст програми:
{Об’явлення змінної i, що використовується в декількох процедурах }
var
i:longint;
{Кнопка “Вихід” }
procedure TForm1.Button3Click(Sender: TObject);
begin
close;
end;
{Кнопка “Новий розв’язок” }
procedure TForm1.Button2Click(Sender: TObject);
begin
for i:=0 to 6 do
begin
stringgrid1.Cells[i,1]:='';
stringgrid2.Cells[i,1]:='';
end;
end;
{Оброблювач події встановлення початкових значень у працюючій програмі}
procedure TForm1.FormCreate(Sender: TObject);
begin
for i:=0 to 6 do
begin
stringgrid1.Cells[i,0]:=inttostr(i+1);
stringgrid2.Cells[i,0]:=inttostr(i+1);
end;
end;
{Кнопка “Сортування”}
procedure TForm1.Button1Click(Sender: TObject);
var
a:array[1..7] of integer;
j:longint;
b:integer; //буферна змінна
begin
//Ініціалізація масива А
for i:=1 to 7 do
a[i]:=strtoint(stringgrid1.Cells[i-1,1]);
//Сортування
for i:=1 to 6 do //Етапи сортування
for j:=1 to 6 do //Кроки сортування
if a[j]>a[j+1] then //Порівняння елемента a[i] з елементом справа від нього
begin //Обмін двох елементів між собою
b:=a[j];
a[j]:=a[j+1];
a[j+1]:=b;
end;
//Виведення у StringGrid2 отсортованого масива
for i:=0 to 6 do stringgrid2.Cells[i,1]:=inttostr(a[i+1]);
end;
Результат роботи програми:
Сортування методом прямого вибору.
Розглянемо той самий одновимірний масив з 5 чисел і виконаємо впорядковування його елементів у бік їх спадання.
Сутність сортування даного масиву методом прямого вибору у бік спадання полягає в слідуючому: у масиві чисел знаходять максимальний елемент і міняють його місцями з першим елементом. Далі знову розглядають масив чисел, але вже без першого елемента. У цій частині масиву теж визначають максимальний елемент і міняють його місцями вже з другим елементом масиву. Далі розглядають частину масиву без двох перших елементів і виконують у ній ті самі дії. Таким чином, елементи масиву розташовуються від найбільшого до найменшого, і масив стає відсортованим.
Розглянемо все сказане на нашому масиві.
Вхідний масив: 2 6 8 1 4.
1 етап. Необхідно знайти максимальний елемент послідовності 2 6 8 1 4 і поставити його на перше місце у масиві. Для цього необхідно:
1 крок. 1-й елемент порівняти з 2-м: 2 < 6. Більше з цих чисел стоїть на другому місці, менше – на першому, а повинно бути навпаки, оскільки масив треба відсортувати від більшого до меншого. Тому треба виконати обмін цих елементів. Новий вигляд масиву: 6 2 8 1 4.
2 крок. 1-й елемент порівнюємо з 3-м: 6 < 8. Знову необхідний обмін елементів. Новий вигляд масиву: 8 2 6 1 4.
3 крок. 1-й елемент порівнюємо з 4-м: 8 > 1. Обмін не потрібний.
4 крок. 1-й елемент порівнюємо з 5-м : 8 < 4. Обмін не потрібний.
Таким чином, на першому місці у масиву з’явився максимальний елемент цього масиву, причому для цього, знадобилося 4 кроки , тобто на 1 менше, ніж елементів у масиву.
2 етап. Розглядатимемо частину масиву без першого елементу, тобто: 2 6 1 4. На цьому етапові виконуються аналогічні дії. На даному етапі результат буде досягнуто з 3 кроки:
1 крок. 1-й елемент порівнюємо з 2-м: 2 < 6. Отже, необхідний обмін елементів. Вигляд масиву після обміну: 6 2 1 4.
2 крок. 1-й елемент порівнюємо з 3-м: 6 > 1. Обмін не потрбний.
3 крок. 1-й елемент порівнюємо з 4-м: 6 > 4. Обмін не потрібний.
Вигляд масиву після двох етапів: 8 6 2 1 4.
Аналогічно, після виконання 3 етапа масив матиме вигляд: 8 6 4 2 1, тобто масив вже отсортований. Але взагалі мажливий ще й 4 етап, тобто максимально можлива кількість етапів сортування – на 1 менше, ніж елементів масиву.
Якщо сортируємо масив за зростанням елементів, все відбувається так само, тільки обмін відбувається, якщо елемент Х виявиться більшим за Y.
Розв’яжемо задачу.
Задача 2. Створити одновимірний масив, що складається з N випадкових чисел у діапазоні від 0 до 50 і відсортувати його у бік спадання методом прямого вибору.
Розв’язування.
Перелік використаних компонентів та їх властивості:
Компонент |
Властивість |
Значення |
Form1 |
Caption |
Сортування методом прямого вибору |
Button1 |
Caption |
Масив випадкових чисел |
Label1 |
Caption |
(вхідний масив) |
Edit1 |
Text |
Тексту немає |
Button2 |
Caption |
Сортування |
Label2 |
Caption |
(відсортований масив) |
Edit2 |
Text |
Тексту немає |
Button3 |
Caption |
Нове рішення |
Button4 |
Caption |
Вихід |
Вигляд форми з поміщеними на ній компонентами:
Текст програми:
{Об’явлення сталої N – кількості елементів масиву}
const n=20;
{Об’явлення змінних i, s, масиву А, що використовуються в декількох процедурах }
var
i:longint;
a:array[1..n] of longint;
s:string;
{Кнопка “Масив випадкових чисел”}
procedure TForm1.Button1Click(Sender: TObject);
begin
randomize;
edit1.Text:='';
for i:=1 to n do
begin
a[i]:=random(50);
str(a[i]:4,s);
edit1.Text:=edit1.Text+s;
end;
end;
{Кнопка “Сортування”}
procedure TForm1.Button2Click(Sender: TObject);
var
m:longint; //Позиція (індекс) максим. елемента
j:longint;
b:longint; //Буферна змінна
begin
//Сортування
for i:=1 to n-1 do //Етапи сортування
begin
m:=i; //Максимальним є і-й елемент
for j:=i+1 to n do //Кроки сортування
if a[j]>a[m] then
m:=j; //Визначено індекс нового максим. елемента на j-й позиції
b:=a[i];
a[i]:=a[m];
a[m]:=b;
end;
//Виведення відсортованого масива у поле Edit2
edit2.Text:='';
for i:=1 to n do
begin
str(a[i]:4,s);
edit2.Text:=edit2.Text+s;
end;
end;
{Кнопка “Новий розв’язок” }
procedure TForm1.Button3Click(Sender: TObject);
begin
edit1.Clear;
edit2.Clear;
end;
{Кнопка “Вихід” }
procedure TForm1.Button4Click(Sender: TObject);
begin
close;
end;
Результат роботи програми: