Опубликовано: 2021-04-21 12:00:00
Сортировка вектора по возрастанию
Одной из основных операций, производимых над массивами, являются операции сортировки или упорядочивания элементов массива по какому-либо признаку: чаще по возрастанию или убыванию – для чисел, и по алфавиту – для символов и строк. Сортировок придумано множество, и, говорят, тому, кто придумает новый эффективный метод сортировки, сразу будет вручена Нобелевская премия. С древних времен до нас дошли два самых простых (конечно, не самых эффективных) способа сортировки, которые мы здесь и рассмотрим.
Задача. Отсортировать одномерный массив (вектор) методом «пузырька» по возрастанию.
Название данного метода часто вызывает нездоровый смех у молодежи, хотя никакого тайного смысла у этого метода нет. Просто он выполняется таким образом, что максимальное число после каждого шага сортировки как бы всплывает в конец массива, на свое заслуженное место.
Заключается метод в следующем: программа, начиная с первых элементов массивов, сравнивает эти элементы попарно, и, в случае, если они расположены не по возрастанию, меняет их местами.
Прежде чем написать полную программу, я попробую объяснить суть работы «пузырькового» метода.
Дан массив: 4 3 2 1.
Рассмотрим по шагам метод «пузырька» для этого массива:
- (3) (4) 2 1
- 3 (2) (4) 1
- 3 2 (1) (4)
- (2) (3) 1 4
- 2 (1) (3) 4
- (1) (2) 3 4
Теперь приступим к основному решению:
- REM VECTOR
- CLS
- RANDOMIZE TIMER
- CONST N = 5 'RAZMER MASSIVA
- DIM A(N)
- 'ZAPOLNENIYE SLUCHAYNYMI CHISLAMI OT 0 DO 10
- A = 0: B = 10
- FOR I = 1 TO N
- A(I) = INT((B - A + 1) * RND + A)
- NEXT I
- 'VIVOD
- PRINT "ISKHODNYY MASSIV:"
- FOR I = 1 TO N
- PRINT USING "##.## "; A(I);
- NEXT I
- 'SORTIROVKA
- FOR I = 1 TO N
- FOR CNT = 1 TO N - 1
- IF (A(CNT) > A(CNT + 1)) THEN
- TEMP = A(CNT)
- A(CNT) = A(CNT + 1)
- A(CNT + 1) = TEMP
- END IF
- NEXT CNT
- NEXT I
- PRINT "UPORYADOCHENNYY PO VOZRASTANIYU:"
- FOR I = 1 TO N
- PRINT USING "##.## "; A(I);
- NEXT I
- END
Рисунок 1 – Исходный текст программы сортировки массива по возрастанию пузырьковым методом
Рисунок 2 – Результат выполнения программы сортировки массива по возрастанию пузырьковым методом
Теперь рассмотрим сортировку выбором.
Допустим, дан числовой массив из N элементов. Надо отсортировать его по возрастанию.
Суть способа в следующем:
- Находим наибольший элемент в массиве и меняем его местами с последним.
- Уменьшаем количество рассматриваемых элементов на 1 (т. к. последний элемент уже на своем месте).
- Повторяем операцию для уменьшенного на единицу массива. И так – N - 1 раз.
Пусть дан массив из пяти элементов: 8 4 9 6 7.
Рассмотрим процесс упорядочивания по шагам:
- 8 4 (7) 6 (9)
- (6) 4 7 (8) 9
- (6) 4 7 (8) 9
- (4) (6) 7 8 9
Пример:
- REM VYBOR
- CLS
- RANDOMIZE TIMER
- CONST N = 5 'RAZMER MASSIVA
- DIM A(N)
- 'ZAPOLNENIYE SLUCHAYNYMI CHISLAMI OT 0 DO 10
- A = 0: B = 10
- FOR I = 1 TO N
- A(I) = INT((B - A + 1) * RND + A)
- NEXT I
- 'VIVOD
- FOR I = 1 TO N
- PRINT USING "## "; A(I);
- NEXT I
- 'VYBOR
- FOR I = 1 TO N - 1
- MIN = I
- FOR CNT = I + 1 TO N
- IF (A(MIN) > A(CNT)) THEN MIN = CNT
- NEXT CNT
- SWAP A(I), A(MIN)
- NEXT I
- 'VIVOD
- FOR I = 1 TO N
- PRINT USING "## "; A(I);
- NEXT I
- END
Рисунок 3 – Исходный текст программы сортировки массива по возрастанию методом выбора
Рисунок 4 – Результат выполнения программы сортировки массива по возрастанию методом выбора
Следующий пример продемонстрирует сортировку по возрастанию методом Шелла (Shall)
- CLS
- RANDOMIZE TIMER
- CONST N = 10
- DIM A(N)
- PRINT "ISKHODNYY MASSIV:"
- A = 0: B = 10
- FOR I = 1 TO N
- A(I) = INT((B - A + 1) * RND + A)
- PRINT USING "##.## "; A(I);
- NEXT
- 'SORTIROVKA SHALL
- D = N \ 2
- WHILE (D > 0)
- DO
- DONE = 1
- FOR I = 1 TO N - D
- IF A(I) > A(I + D) THEN
- SWAP (A(I)), (A(I + D)) 'OBMEN ZNACHENIY DVUKH PEREMENNYKH
- DONE = 0
- END IF
- NEXT
- LOOP UNTIL DONE
- D = D \ 2
- WEND
- PRINT "UPORYADOCHENNYY PO VOZRASTANIYU:"
- FOR I = 1 TO N
- PRINT USING "##.## "; A(I);
- NEXT
- END
Рисунок 5 – Исходный текст программы сортировки массива по возрастанию методом Шелла
Рисунок 6 – Результат выполнения программы сортировки массива по возрастанию методом Шелла
Новым здесь является оператор SWAP. Синтаксис:
SWAP <переменная_1>, <переменная_2>
Обмен значениями с помощью оператора SWAP может выполняться для любых типов переменных (целых, с обычной точностью, с двойной точностью, строковых), однако, обе переменные должны иметь один и тот же тип. В противном случае возникает ошибка «Type mismatch».
Самостоятельно разберитесь в работе этих программ. Попробуйте отобразить работу этих методов на бумаге, если не получится, обратитесь к поисковикам сети Интернет или в комментарии.
Ниже представлены задачи для самостоятельного изучения.
Задача: Дан массив переменных A(10), который заполнен последовательностью чисел от 1 до 10. С помощью различных методов, отсортировать его по убыванию.
Сортировка методом пузырька:
- N = 10
- DIM A(N)
- FOR I = 1 TO N
- A(I) = I
- NEXT
- FOR I = 1 TO N
- PRINT A(I);
- NEXT
- FOR I = 1 TO N - 1
- FOR J = 1 TO N - I
- IF A(J) < A(J + 1) THEN SWAP A(J), A(J + 1)
- NEXT
- NEXT
- FOR I = 1 TO N
- PRINT A(I);
- NEXT
Рисунок 7 – Исходный текст программы сортировки массива по убыванию методом пузырька
Рисунок 8 – Результат выполнения программы сортировки массива по убыванию методом пузырька
Сортировка методом вставки:
- CONST N = 10
- DIM A(N)
- FOR I = 1 TO N
- A(I) = I
- NEXT
- FOR I = 1 TO N
- PRINT A(I);
- NEXT
- FOR I = 1 TO N
- X = A(I)
- J = I - 1
- WHILE J > 0 AND A(J) < X
- A(J + 1) = A(J)
- J = J - 1
- WEND
- A(J + 1) = X
- NEXT
- FOR I = 1 TO N
- PRINT A(I);
- NEXT
Рисунок 9 – Исходный текст программы сортировки массива по убыванию методом вставки
Рисунок 10 – Результат выполнения программы сортировки массива по убыванию методом вставки
Сортировка методом выбора:
- N = 10
- DIM A(N)
- FOR I = 1 TO N
- A(I) = I
- NEXT
- FOR I = 1 TO N
- PRINT A(I);
- NEXT
- FOR I = 1 TO N
- MAX = A(I)
- K = I
- FOR J = I + 1 TO N
- IF A(J) > MAX THEN MAX = A(J): K = J
- NEXT
- SWAP A(I), A(K)
- NEXT
- FOR I = 1 TO N
- PRINT A(I);
- NEXT
Рисунок 11 – Исходный текст программы сортировки массива по убыванию методом выбора
Рисунок 12 – Результат выполнения программы сортировки массива по убыванию методом выбора
Вот ещё один вариант с чуть более нагруженным внутренним циклом, но с меньшей инициализаций его же.
Назовём эту штуку «двусторонняя» сортировка выбором:
- DATA -4,3,4,3,4,5,9,8,5,9
- CLS
- FOR I = 1 TO 10: READ A(I): PRINT A(I);: NEXT
- FOR I = 0 TO 4
- MNI = 1 + I: MXI = MNI
- MIN = A(MNI): MAX = MIN
- FOR N = 1 + I TO 10 - I
- IF A(N) > MAX THEN MAX = A(N): MXI = N
- IF A(N) < MIN THEN MIN = A(N): MNI = N
- NEXT
- SWAP A(1 + I), MAX
- SWAP A(10 - I), MIN
- NEXT
- FOR I = 1 TO 10: PRINT A(I);: NEXT
Рисунок 13 – Исходный текст программы сортировки массива по убыванию «двусторонним» методом выбора
Рисунок 14 – Результат выполнения программы сортировки массива по убыванию «двусторонним» методом выбора
Ограничение этого метода: Должно быть чётное число элементов.
Алгоритм легко масштабируется (для случаев с количеством элементов кратных 4, 8, и т.д.). Полагаю, что он уступает сложным алгоритмам, например, QSort'у (быстрая сортировка), но зато не требует дополнительной памяти, легко реализуется (без структур типа «бинарное дерево») и не «страдает» от «плохого» распределения данных.
Для сравнения сортировка 15000 чисел (на QB64):
- Этим алгоритмом: ~22.5 сек
- Сортировкой выбором: ~35.5 сек
Спасибо за прочтение этой статьи.