Алгоритм сортировки сегментов (Java, Python, С /C++ Code Примеры)
⚡ Умное резюме
Сортировка по корзинам распределяет входные элементы по нескольким корзинам, сортирует каждую корзину независимо и объединяет их для получения итогового отсортированного массива.

Что такое групповая сортировка?
Сортировка по корзинам, часто называемая сортировкой по контейнерам, — это метод сортировки распределения на основе сравнения, который принимает на вход несортированный массив и выдает на выходе отсортированный массив. Этот метод распределяет элементы по нескольким корзинам и сортирует каждую корзину по отдельности, используя другой алгоритм сортировки, например, сортировку вставками. Затем все корзины объединяются, образуя окончательный отсортированный массив.
Сортировка по корзинам обычно используется, когда элементами являются:
- Значения с плавающей запятой
- Равномерно распределен в известном диапазоне
Временная сложность алгоритма сортировки по корзинам зависит от количества используемых корзин и равномерности распределения входных данных. В то время как другие алгоритмы сортировки, такие как… сортировка по скорлупе, сортировка слиянием, пирамидальная сортировка и быстрая сортировка Для достижения наилучшей временной сложности O(n*logn) алгоритм сортировки по корзинам может достичь линейной временной сложности O(n) при благоприятных условиях.
Сортировка по корзинам использует подход «рассеивание-сбор». Элементы распределяются по соответствующим корзинам, сортируются внутри каждой корзины и на заключительном этапе собираются в отсортированный массив. Этот подход «рассеивание-сбор» обсуждается в следующем разделе.
Метод рассеяния-сбора
Крупномасштабные и сложные задачи порой бывает трудно решить напрямую. Метод «рассеянного сбора данных» решает такие проблемы, разделяя весь набор данных на кластеры. Каждый кластер обрабатывается отдельно, а результаты объединяются для получения окончательного ответа.
Вот как алгоритм сортировки по корзинам реализует метод рассеяния-сбора:
Как работает сегментная сортировка
Основной принцип работы сортировки по корзинам следующий:
- Создается набор пустых контейнеров. В зависимости от выбранной политики количество контейнеров может варьироваться.
- Из входного массива каждый элемент помещается в соответствующую ему ячейку.
- Каждый сегмент сортируется индивидуально с использованием вторичного алгоритма сортировки.
- Отсортированные сегменты объединяются для получения единого выходного массива.
Прозвище Code
Start Create N empty buckets For each array element: Calculate bucket index Put that element into the corresponding bucket For each bucket: Sort elements within each bucket Merge all the elements from each bucket Output the sorted array End
Метод 1. Алгоритм сортировки сегментов для чисел с плавающей запятой Numbers
Алгоритм сортировки по корзинам для чисел с плавающей запятой в диапазоне [0.0, 1.0]:
Шаг 1) Создайте десять (10) пустых корзин. Первая корзина содержит числа в диапазоне [0.0, 0.1], вторая корзина содержит [0.1, 0.2) и так далее.
Шаг 2) Для каждого элемента массива:
- а. Рассчитайте индекс корзины, используя формулу:
bucket_index = no_of_buckets * array_element - b. Вставьте элемент в контейнер bucket[bucket_index]
Шаг 3) Отсортируйте каждую корзину по отдельности, используя сортировку вставками.
Шаг 4) Объедините все корзины в один отсортированный массив.
Рассмотрим пример сортировки по корзинам. В этом примере мы отсортируем следующий массив:
Шаг 1) Сначала создадим 10 пустых корзин. В первой корзине будут храниться числа в диапазоне [0.0, 0.1], во второй — [0.1, 0.2], и так далее.
Шаг 2) Для каждого элемента массива вычислите индекс корзины и поместите элемент в эту корзину.
Индекс корзины рассчитывается по формуле:
bucket_index = no_of_buckets * array_element
Расчет индекса ковша:
а) 0.78
bucket_index = no_of_buckets * array_element
= 10 * 0.78
= 7.8
Следовательно, элемент 0.78 хранится в bucket[floor(7.8)] или bucket[7].
б) 0.17
bucket_index = no_of_buckets * array_element
= 10 * 0.17
= 1.7
Элемент массива 0.17 хранится в bucket[floor(1.7)] или bucket[1].
в) 0.39
bucket_index = no_of_buckets * array_element
= 10 * 0.39
= 3.9
0.39 хранится в bucket[floor(3.9)] или bucket[3].
После перебора всех элементов массива, содержимое сегментов будет выглядеть следующим образом:
Шаг 3) Затем каждая ячейка сортируется с помощью сортировки вставками. После операции сортировки получается следующий результат:
Шаг 4) На заключительном этапе все элементы объединяются в один массив. Этот массив представляет собой отсортированный результат обработки входных данных.
Каждый сегмент добавляется к выходному массиву. Например, конкатенация элементов второго сегмента:
Ниже показано соединение последних элементов корзины:
После конкатенации полученный массив представляет собой желаемый отсортированный массив.
Программа сортировки сегментов на C/C++
Входной сигнал:
//Bucket Sort Program in C/C++ //For values without integer parts #include <bits/stdc++.h> #define BUCKET_SIZE 10 using namespace std; void bucketSort(float input[], int array_size) { vector <float>bucket[BUCKET_SIZE]; for (int i = 0; i < array_size; i++) { int index = BUCKET_SIZE*input[i]; bucket[index].push_back(input[i]); } for (int i = 0; i < BUCKET_SIZE; i++) sort(bucket[i].begin(), bucket[i].end()); int out_index = 0; for (int i = 0; i < BUCKET_SIZE; i++) for (int j = 0; j < bucket[i].size(); j++) input[out_index++] = bucket[i][j]; } int main() { float input[]={0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.69}; int array_size = sizeof(input)/sizeof(input[0]); bucketSort(input, array_size); cout <<"Sorted Output: "; for (int i = 0; i< array_size; i++) cout<<input[i]<<" "; return 0; }
Выход:
Sorted Output: 0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94
Программа сортировки сегментов в Python
Входной сигнал:
# Bucket Sort Program in Python # For values without integer parts def bucketSort(input): output = [] bucket_size = 10 for bucket in range(bucket_size): output.append([]) for element in input: index = int(bucket_size * element) output[index].append(element) for bucket in range(bucket_size): output[bucket] = sorted(output[bucket]) out_index = 0 for bucket in range(bucket_size): for element in range(len(output[bucket])): input[out_index] = output[bucket][element] out_index += 1 return input input = [0.78, 0.17, 0.39, 0.26, 0.72, 0.94, 0.21, 0.12, 0.23, 0.69] print("Sorted Output:") print(bucketSort(input))
Выход:
Sorted Output: [0.12, 0.17, 0.21, 0.23, 0.26, 0.39, 0.69, 0.72, 0.78, 0.94]
Ведро сортировки Java
Входной сигнал:
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BucketSort { private static final int BUCKET_SIZE = 10; public static void bucketSort(float[] input, int arraySize) { List<Float>[] bucket = new ArrayList[BUCKET_SIZE]; for (int i = 0; i < arraySize; i++) { int index = (int)(BUCKET_SIZE * input[i]); if (bucket[index] == null) { bucket[index] = new ArrayList<>(); } bucket[index].add(input[i]); } for (int i = 0; i < BUCKET_SIZE; i++) { if (bucket[i] != null) { Collections.sort(bucket[i]); } } int outIndex = 0; for (int i = 0; i < BUCKET_SIZE; i++) { if (bucket[i] != null) { for (float value: bucket[i]) { input[outIndex++] = value; } } } } public static void main(String[] args) { float[] input = {0.78f,0.17f,0.39f,0.26f,0.72f,0.94f,0.21f,0.12f,0.23f,0.69f}; int arraySize = input.length; bucketSort(input, arraySize); System.out.println("Sorted Output:"); for (int i = 0; i < arraySize; i++) { System.out.print(input[i]+" "); } } }
Выход:
Sorted Output: 0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94
Метод 2. Алгоритм групповой сортировки для целочисленных элементов
Алгоритм сортировки по корзинам для входных данных, содержащих числа, выходящие за пределы диапазона [0.0, 1.0], немного отличается от предыдущего. алгоритмДля решения данной задачи необходимы следующие шаги:
Шаг 1) Найдите максимальный и минимальный элементы в массиве.
Шаг 2) Выберите количество корзин n и инициализируйте их пустыми.
Шаг 3) Рассчитайте диапазон или диапазон каждого сегмента, используя формулу:
span = (maximum - minimum) / n
Шаг 4) Для каждого элемента массива:
- 1. Рассчитайте индекс корзины:
bucket_index = (element - minimum) / span - 2. Вставьте элемент в контейнер bucket[bucket_index]
Шаг 5) Отсортируйте каждый сегмент, используя сортировку вставками.
Шаг 6) Объедините все сегменты в один массив.
Рассмотрим пример алгоритма сортировки по корзинам. В этом примере мы отсортируем следующий массив:
Шаг 1) На первом шаге мы находим максимальный и минимальный элементы заданного массива. В этом примере максимум равен 24, а минимум — 1.
Шаг 2) Далее мы выбираем количество пустых ячеек, n. В этом примере мы используем 5 ячеек и инициализируем их как пустые.
Шаг 3) Размер каждого контейнера рассчитывается по формуле:
span = (maximum - minimum) / n = (24 - 1) / 5 = 4
Таким образом, в первом контейнере находятся числа в диапазоне [0, 5], во втором — [5, 10), и так далее.
Шаг 4) Для каждого элемента массива вычислите индекс корзины и поместите элемент в эту корзину. Индекс корзины вычисляется по формуле:
bucket_index = (element - minimum) / span
Расчет индекса ковша:
а) 11
bucket_index = (element – minimum) / span
= (11-1) / 4
= 2
Таким образом, элемент 11 хранится в корзине[2].
б) 9
bucket_index = (element – minimum) / span
= (9-1) / 4
= 2
Примечание: Поскольку 9 является граничным элементом для bucket[1], он добавляется к bucket[1], а не помещается в тот же bucket, что и предыдущий элемент.
После выполнения операций для каждого элемента, корзины выглядят следующим образом:
Шаг 5) Теперь каждая группа сортируется с помощью сортировки вставками. Группы после сортировки:
Шаг 6) На заключительном этапе корзины объединяются в один массив. массив — это отсортированный результат входных данных.
Программа сортировки сегментов на C/C++
Входной сигнал:
#include<bits/stdc++.h> using namespace std; void bucketSort(vector < double > & input, int No_Of_Buckets) { double max_value = * max_element(input.begin(), input.end()); double min_value = * min_element(input.begin(), input.end()); double span = (max_value - min_value) / No_Of_Buckets; vector<vector <double>> output; for (int i = 0; i < No_Of_Buckets; i++) output.push_back(vector <double>()); for (int i = 0; i < input.size(); i++) { double difference = (input[i] - min_value) / span - int((input[i] - min_value) / span); if (difference == 0 && input[i] != min_value) output[int((input[i] - min_value) / span) - 1].push_back(input[i]); else output[int((input[i] - min_value) / span)].push_back(input[i]); } for (int i = 0; i < output.size(); i++) { if (!output[i].empty()) sort(output[i].begin(), output[i].end()); } int index = 0; for (vector <double> & bucket: output) { if (!bucket.empty()) { for (double i: bucket) { input[index] = i; index++; } } } } int main() { vector <double> input ={11,9,21,8,17,19,13,1,24,12}; int No_Of_Buckets = 5; bucketSort(input, No_Of_Buckets); cout<<"Sorted Output:"; for (int i=0; i < input.size(); i++) cout <<input[i]<<" "; return 0; }
Выход:
Sorted Output:1 8 9 11 12 13 17 19 21 24
Программа сортировки сегментов в Python
Входной сигнал:
def bucketSort(input, No_Of_Buckets): max_element = max(input) min_element = min(input) span = (max_element - min_element) / No_Of_Buckets output = [] for bucket in range(No_Of_Buckets): output.append([]) for element in range(len(input)): diff = (input[element] - min_element) / span - int( (input[element] - min_element) / span ) if diff == 0 and input[element] != min_element: output[int((input[element] - min_element) / span) - 1].append( input[element] ) else: output[int((input[element] - min_element) / span)].append(input[element]) for bucket in range(len(output)): if len(output[bucket]) != 0: output[bucket].sort() index = 0 for bucket in output: if bucket: for element in bucket: input[index] = element index = index + 1 input = [11, 9, 21, 8, 17, 19, 13, 1, 24, 12] No_Of_Buckets = 5 bucketSort(input, No_Of_Buckets) print("Sorted Output: ", input)
Выход:
Sorted Output: [1, 8, 9, 11, 12, 13, 17, 19, 21, 24]
Ведро сортировки Java
Входной сигнал:
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BucketSort { public static void bucketSort(List < Double > input, int No_Of_Buckets) { double max_value = Collections.max(input); double min_value = Collections.min(input); double span =(max_value - min_value) / No_Of_Buckets; List<List<Double>> output = new ArrayList<>(); for (int i = 0; i < No_Of_Buckets; i++) { output.add(new ArrayList<>()); } for (Double value: input) { double difference = (value - min_value) / span - ((value - min_value) / span); if (difference == 0 && value != min_value) { output.get((int)((value - min_value) / span) - 1).add(value); } else { output.get((int)((value - min_value) / span)).add(value); } } for (List <Double> bucket: output) { if (!bucket.isEmpty()) { Collections.sort(bucket); } } int index = 0; for (List <Double> bucket: output) { if (!bucket.isEmpty()) { for (Double value: bucket) { input.set(index,value); index++; } } } } public static void main(String[] args) { List <Double> input = new ArrayList<>(); input.add(11.0); input.add(9.0); input.add(21.0); input.add(8.0); input.add(17.0); input.add(19.0); input.add(13.0); input.add(1.0); input.add(24.0); input.add(12.0); int No_Of_Buckets = 5; bucketSort(input, No_Of_Buckets); System.out.println("Sorted Output:"); for (Double value: input) { System.out.print(value + " "); } } }
Выход:
Sorted Output: 1.0 8.0 9.0 11.0 12.0 13.0 17.0 19.0 21.0 24.0
Плюсы и минусы сортировки по категориям
| Плюсы | Минусы |
|---|---|
| Выполняет более быстрые вычисления на равномерно распределенных данных. | Занимает больше места по сравнению с алгоритмами сортировки на месте. |
| Может использоваться в качестве внешнего метода сортировки для больших наборов данных. | Плохо работает, когда данные распределены неравномерно. |
| Обработка отдельных блоков данных может осуществляться как независимо, так и параллельно. | Требуется предварительное знание диапазона и распределения данных. |
Анализ сложности сегментной сортировки
Сложность времени сортировки ведра
- лучшая сложность дела: Если все элементы массива равномерно распределены и предварительно отсортированы внутри каждой ячейки, то для распределения элементов по соответствующим ячейкам потребуется время O(n). Затем сортировка каждой ячейки осуществляется с помощью сортировка вставок Стоимость составляет O(k). Таким образом, общая сложность равна O(n+k).
- Средняя сложность дела: В усредненных случаях мы предполагаем, что входные данные распределены равномерно. Таким образом, алгоритм сортировки по корзинам достигает линейной временной сложности O(n+k). Здесь для распределения элементов требуется O(n) времени, а для их сортировки с помощью сортировки вставками — O(k) времени.
- Наихудшая сложность случая: В худшем случае элементы распределены неравномерно и концентрируются в одном или двух сегментах. В этом случае сортировка сегментами (Bucket Sort) начинает вести себя аналогично... алгоритм пузырьковой сортировкиСледовательно, в худшем случае временная сложность сортировки по корзинам составляет O(n²).
Пространственная сложность сортировки ведром
Пространственная сложность сортировки по корзинам составляет O(n*k). Здесь n — количество элементов, а k — количество корзин, необходимых для их хранения во время сортировки.


















