Сортировка пузырьком
Последнее обновление
Сортировка пузырьком многократно проходит по списку, сравнивает каждую пару соседних элементов и меняет их местами, если они стоят в неправильном порядке. После каждого полного прохода наибольшее из оставшихся значений «всплывает» на своё правильное место в конце, поэтому каждый следующий проход рассматривает на один элемент меньше. Нажмите «воспроизвести» выше, чтобы увидеть сравнения и обмены, или проходите их по одному.
Это один из самых простых для понимания алгоритмов сортировки, что делает его отличным первым алгоритмом, но время выполнения O(n²) делает его непрактичным для больших входных данных.
Временная и пространственная сложность
| Случай | Сложность | Примечания |
|---|---|---|
| Лучший случай | O(n) | Уже отсортирован, с проверкой досрочного выхода |
| Средний случай | O(n²) | Случайный порядок |
| Худший случай | O(n²) | Отсортирован в обратном порядке |
| Память | O(1) | На месте, только временная переменная |
| Устойчивая | Да | Равные элементы сохраняют свой относительный порядок |
Шаг за шагом
| Шаг | Что происходит |
|---|---|
| 1 | Начните с начала массива. |
| 2 | Сравните текущий элемент со следующим. |
| 3 | Если они в неправильном порядке, поменяйте их местами. |
| 4 | Сдвиньтесь на одну позицию вправо и повторяйте до конца (один проход). |
| 5 | Повторяйте проходы; каждый проход фиксирует ещё один элемент в конце. |
| 6 | Остановитесь, когда полный проход не сделает ни одного обмена. |
Разобранный пример
Сортировка [5, 2, 4, 1]:
| Проход | Массив | Действие |
|---|---|---|
| 1 | [2, 4, 1, 5] | Обмен 5,2, затем 5,4, затем 5,1; 5 всплывает в конец. |
| 2 | [2, 1, 4, 5] | 2,4 в порядке; обмен 4,1; 4,5 в порядке; 4 теперь на месте. |
| 3 | [1, 2, 4, 5] | Обмен 2,1; остальное уже в порядке; 2 на месте. |
| 4 | [1, 2, 4, 5] | Полный проход не делает обменов, поэтому массив отсортирован и алгоритм останавливается. |
Когда использовать сортировку пузырьком
| Используйте, когда | Избегайте, когда |
|---|---|
| Вы обучаете или изучаете, как работают сортировки на основе сравнений | Вы сортируете большие входные данные, где O(n²) слишком медленно |
Вход крошечный или почти отсортирован (с досрочным выходом приближается к O(n)) | Вам нужна самая быстрая универсальная сортировка — используйте quicksort или merge sort |
| Вам нужна устойчивая сортировка на месте почти без кода | Данные в случайном порядке и важна производительность |
| Вы определяете за один проход, отсортирован ли уже короткий список | Многочисленные записи дороги (напр. флеш-память); сортировка выбором делает меньше обменов |
Код Bubble Sort
Чистая, готовая к запуску реализация Bubble Sort на Python, JavaScript, Java, C++, C. Выберите язык, скопируйте код или откройте его уже загруженным в плейграунде Coddy.
Код Bubble Sort на Python
1def bubble_sort(a):2 n = len(a)3 for i in range(n - 1):4 swapped = False5 for j in range(n - 1 - i):6 if a[j] > a[j + 1]:7 a[j], a[j + 1] = a[j + 1], a[j]8 swapped = True9 if not swapped:10 break # no swaps means the list is already sorted11 return a12
13
14nums = [5, 1, 4, 2, 8]15print("Before:", nums)16bubble_sort(nums)17print("After: ", nums)Код Bubble Sort на JavaScript
1function bubbleSort(a) {2 for (let end = a.length - 1; end > 0; end--) {3 let swapped = false;4 for (let j = 0; j < end; j++) {5 if (a[j] > a[j + 1]) {6 [a[j], a[j + 1]] = [a[j + 1], a[j]];7 swapped = true;8 }9 }10 if (!swapped) break; // Already sorted: stop early11 }12 return a;13}14
15const data = [5, 2, 9, 1, 7, 3];16console.log("Before:", data);17console.log("Sorted:", bubbleSort([...data]));Код Bubble Sort на Java
1import java.util.Arrays;2
3public class Main {4 static void bubbleSort(int[] arr) {5 for (int i = arr.length - 1; i > 0; i--) {6 boolean swapped = false;7 for (int j = 0; j < i; j++) {8 if (arr[j] > arr[j + 1]) {9 int tmp = arr[j];10 arr[j] = arr[j + 1];11 arr[j + 1] = tmp;12 swapped = true;13 }14 }15 if (!swapped) break; // already sorted16 }17 }18
19 public static void main(String[] args) {20 int[] arr = {5, 1, 4, 2, 8, 3};21 System.out.println("Before: " + Arrays.toString(arr));22 bubbleSort(arr);23 System.out.println("After: " + Arrays.toString(arr));24 }25}Код Bubble Sort на C++
1#include <iostream>2#include <utility>3#include <vector>4
5void printVec(const std::vector<int>& a) {6 for (int x : a) std::cout << x << " ";7 std::cout << "\n";8}9
10void bubbleSort(std::vector<int>& a) {11 for (size_t pass = 0; pass + 1 < a.size(); ++pass) {12 bool swapped = false;13 // Each pass bubbles the largest remaining value to the end14 for (size_t j = 0; j + 1 < a.size() - pass; ++j) {15 if (a[j] > a[j + 1]) {16 std::swap(a[j], a[j + 1]);17 swapped = true;18 }19 }20 if (!swapped) break; // already sorted21 }22}23
24int main() {25 std::vector<int> data = {5, 1, 4, 2, 8, 3};26 std::cout << "Before: ";27 printVec(data);28 bubbleSort(data);29 std::cout << "After: ";30 printVec(data);31 return 0;32}Код Bubble Sort на C
1#include <stdbool.h>2#include <stdio.h>3
4void printArr(const int a[], int n) {5 for (int i = 0; i < n; i++) printf("%d ", a[i]);6 printf("\n");7}8
9void bubbleSort(int a[], int n) {10 for (int pass = 0; pass < n - 1; pass++) {11 bool swapped = false;12 // Each pass bubbles the largest remaining value to the end13 for (int j = 0; j < n - 1 - pass; j++) {14 if (a[j] > a[j + 1]) {15 int tmp = a[j];16 a[j] = a[j + 1];17 a[j + 1] = tmp;18 swapped = true;19 }20 }21 if (!swapped) break; // already sorted22 }23}24
25int main(void) {26 int data[] = {5, 1, 4, 2, 8, 3};27 int n = sizeof(data) / sizeof(data[0]);28 printf("Before: ");29 printArr(data, n);30 bubbleSort(data, n);31 printf("After: ");32 printArr(data, n);33 return 0;34}Часто задаваемые вопросы о сортировке пузырьком
Какова временная сложность сортировки пузырьком?
O(n²) в среднем и худшем случаях из-за вложенных циклов. С оптимизацией досрочного выхода она может достигать O(n) на уже отсортированном массиве. Она использует O(1) дополнительной памяти.Является ли сортировка пузырьком устойчивой?
Почему её называют сортировкой пузырьком?
В чём разница между сортировкой пузырьком и сортировкой вставками?
O(n²), устойчивы и работают на месте, но перемещают данные по-разному: сортировка пузырьком многократно меняет местами соседние неупорядоченные пары, тогда как сортировка вставками берёт каждый элемент и вставляет его на правильное место в отсортированном префиксе. Сортировка вставками обычно делает меньше записей и на практике быстрее, особенно на почти отсортированных данных.Когда стоит использовать сортировку пузырьком вместо quicksort?
O(n log n) у quicksort разгромно превосходит O(n²) сортировки пузырьком на всём, кроме крошечных входных данных. Сортировка пузырьком оправдана, только когда список очень мал или почти отсортирован, либо когда нужна максимально простая устойчивая сортировка для обучения.Меняет ли оптимизация досрочного выхода худший случай сортировки пузырьком?
O(n) на уже отсортированном входе, но массиву, отсортированному в обратном порядке, по-прежнему нужны все сравнения, поэтому худший случай остаётся O(n²). Оптимизация помогает только в лучшем и почти отсортированных случаях.