Сортировка массива методом пузырька
Условие
Напишите процедуру сортировки массива чисел методом пузырька (bubble sort).
Алгоритм:
- Сравниваем соседние элементы массива
- Если текущий элемент больше следующего — меняем их местами
- Повторяем проходы по массиву, пока не будет ни одной перестановки
Пример
Вход: [5, 2, 8, 1, 9] Выход: [1, 2, 5, 8, 9]
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Обзор задачи
Метод пузырька (Bubble Sort) — один из самых простых алгоритмов сортировки, хотя и не самый эффективный. Его название происходит от процесса: наибольшие элементы "всплывают" к концу массива за счёт повторяющихся проходов и обменов. Это классическая задача на собеседовании, которая проверяет понимание циклов, массивов и логики алгоритмов.
Математическая сложность
- Временная сложность: O(n²) в худшем и среднем случаях
- Пространственная сложность: O(1) — сортировка на месте
- Устойчивость: Да, относительный порядок равных элементов сохраняется
- Лучший случай: O(n) при уже отсортированном массиве (с оптимизацией флага)
Реализация 1: Базовый вариант
Процедура БыстраяСортировкаПузырьком(Массив)
КоличествоЭлементов = Массив.Количество();
// Внешний цикл — количество проходов
Для Проход = 0 По КоличествоЭлементов - 2 Цикл
// Внутренний цикл — сравнение соседних элементов
Для Индекс = 0 По КоличествоЭлементов - 2 - Проход Цикл
// Если текущий элемент больше следующего — меняем местами
Если Массив[Индекс] > Массив[Индекс + 1] Тогда
Временное = Массив[Индекс];
Массив[Индекс] = Массив[Индекс + 1];
Массив[Индекс + 1] = Временное;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Реализация 2: С оптимизацией флага
Процедура БыстраяСортировкаПузырькомОптимизированная(Массив)
КоличествоЭлементов = Массив.Количество();
БылиОбмены = Истина;
Проход = 0;
// Продолжаем проходы, пока есть обмены
Пока БылиОбмены Цикл
БылиОбмены = Ложь;
// Сравниваем соседние элементы
Для Индекс = 0 По КоличествоЭлементов - 2 - Проход Цикл
Если Массив[Индекс] > Массив[Индекс + 1] Тогда
// Обмен
Временное = Массив[Индекс];
Массив[Индекс] = Массив[Индекс + 1];
Массив[Индекс + 1] = Временное;
// Отмечаем, что был произведён обмен
БылиОбмены = Истина;
КонецЕсли;
КонецЦикла;
Проход = Проход + 1;
КонецЦикла;
КонецПроцедуры
Реализация 3: С поддержкой функции сравнения
Процедура БыстраяСортировкаПузырькомУниверсальная(Массив, ФункцияСравнения = Неопределено)
КоличествоЭлементов = Массив.Количество();
БылиОбмены = Истина;
Проход = 0;
// Если функция сравнения не передана, используем стандартное сравнение
Если ФункцияСравнения = Неопределено Тогда
Пока БылиОбмены Цикл
БылиОбмены = Ложь;
Для Индекс = 0 По КоличествоЭлементов - 2 - Проход Цикл
Если Массив[Индекс] > Массив[Индекс + 1] Тогда
Временное = Массив[Индекс];
Массив[Индекс] = Массив[Индекс + 1];
Массив[Индекс + 1] = Временное;
БылиОбмены = Истина;
КонецЕсли;
КонецЦикла;
Проход = Проход + 1;
КонецЦикла;
Иначе
// Используем переданную функцию для сравнения
Пока БылиОбмены Цикл
БылиОбмены = Ложь;
Для Индекс = 0 По КоличествоЭлементов - 2 - Проход Цикл
Если ФункцияСравнения(Массив[Индекс], Массив[Индекс + 1]) > 0 Тогда
Временное = Массив[Индекс];
Массив[Индекс] = Массив[Индекс + 1];
Массив[Индекс + 1] = Временное;
БылиОбмены = Истина;
КонецЕсли;
КонецЦикла;
Проход = Проход + 1;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Реализация 4: С отладочной информацией
Процедура БыстраяСортировкаПузырькомСОтладкой(Массив, ВыводОтладки = Ложь)
КоличествоЭлементов = Массив.Количество();
БылиОбмены = Истина;
Проход = 0;
КоличествоОбменов = 0;
КоличествоСравнений = 0;
Если ВыводОтладки Тогда
Сообщить("Начальный массив: " + МассивВСтроку(Массив));
КонецЕсли;
Пока БылиОбмены Цикл
БылиОбмены = Ложь;
Для Индекс = 0 По КоличествоЭлементов - 2 - Проход Цикл
КоличествоСравнений = КоличествоСравнений + 1;
Если Массив[Индекс] > Массив[Индекс + 1] Тогда
Временное = Массив[Индекс];
Массив[Индекс] = Массив[Индекс + 1];
Массив[Индекс + 1] = Временное;
БылиОбмены = Истина;
КоличествоОбменов = КоличествоОбменов + 1;
Если ВыводОтладки Тогда
Сообщить("Проход " + Проход + ": обмен элементов [" + Индекс + "] и [" + (Индекс + 1) + "]");
КонецЕсли;
КонецЕсли;
КонецЦикла;
Проход = Проход + 1;
КонецЦикла;
Если ВыводОтладки Тогда
Сообщить("Финальный массив: " + МассивВСтроку(Массив));
Сообщить("Всего сравнений: " + КоличествоСравнений);
Сообщить("Всего обменов: " + КоличествоОбменов);
Сообщить("Количество проходов: " + Проход);
КонецЕсли;
КонецПроцедуры
Функция МассивВСтроку(Массив)
РезультатПо = "[";
Для И = 0 По Массив.Количество() - 1 Цикл
Если И > 0 Тогда
РезультатПо = РезультатПо + ", ";
КонецЕсли;
РезультатПо = РезультатПо + Массив[И];
КонецЦикла;
РезультатПо = РезультатПо + "]";
Возврат РезультатПо;
КонецФункции
Примеры использования
// Пример 1: базовое использование
Массив1 = Новый Массив();
Массив1.Добавить(5);
Массив1.Добавить(2);
Массив1.Добавить(8);
Массив1.Добавить(1);
Массив1.Добавить(9);
БыстраяСортировкаПузырькомОптимизированная(Массив1);
Сообщить("Отсортированный массив: " + МассивВСтроку(Массив1)); // [1, 2, 5, 8, 9]
// Пример 2: с отладкой
Массив2 = Новый Массив();
Массив2.Добавить(3);
Массив2.Добавить(1);
Массив2.Добавить(4);
Массив2.Добавить(1);
Массив2.Добавить(5);
БыстраяСортировкаПузырькомСОтладкой(Массив2, Истина);
Анализ сложности на примере [5, 2, 8, 1, 9]
Проход 1: 5 сравнений, 4 обмена (9 всплывает в конец) Проход 2: 4 сравнения, 3 обмена (8 встаёт на место) Проход 3: 3 сравнения, 2 обмена (5 встаёт на место) Проход 4: 2 сравнения, 1 обмен (2 встаёт на место) Проход 5: 1 сравнение, 0 обменов (массив отсортирован)
Итого: 15 сравнений, 10 обменов
Рекомендация
Для production-кода используйте оптимизированный вариант (реализация 2) — он автоматически останавливается при отсортированном массиве, что может значительно ускорить работу в лучших случаях.