当输入在一个范围内均匀分布时,存储桶排序主要有用。例如对于请考虑以下问题。
对一大组浮点数进行排序,这些浮点数的范围从0.0到1.0,并且在整个范围内均匀分布。我们如何有效地对数字进行排序?
一种简单的方法是应用基于比较的排序算法。基于比较的排序算法(合并排序,堆排序,快速排序等)的下限是Ω(n Log n),即它们不能比nLogn更好。
我们可以按线性时间对数组排序吗?计数排序不能在这里应用,因为我们在计数排序中使用键作为索引。这里的键是浮点数。
这个想法是使用存储桶排序。以下是存储桶算法。
bucketSort(arr[], n)
1) Create n empty buckets (Or lists).
2) Do following for every array element arr[i].
.......a) Insert arr[i] into bucket[n*array[i]]
3) Sort individual buckets using insertion sort.
4) Concatenate all sorted buckets.
时间复杂度:如果我们假设在存储桶中插入需要O(1)时间,则上述算法的步骤1和2显然需要O(n)时间。如果我们使用链表表示存储桶,则O(1)很容易实现(在以下代码中,为简单起见,使用C++向量)。第4步还需要O(n)时间,因为所有存储桶中将有n个项目。
要分析的主要步骤是步骤3。如果所有数字都均匀分布,则此步骤平均还需要O(n)时间(请参阅CLRS书以获取更多详细信息)
以下是上述算法的实现。
C++
// C++ program to sort an
// array using bucket sort
#include
#include
#include
using namespace std;
// Function to sort arr[] of
// size n using bucket sort
void bucketSort(float arr[], int n)
{
// 1) Create n empty buckets
vector b[n];
// 2) Put array elements
// in different buckets
for (int i = 0; i < n; i++) {
int bi = n * arr[i]; // Index in bucket
b[bi].push_back(arr[i]);
}
// 3) Sort individual buckets
for (int i = 0; i < n; i++)
sort(b[i].begin(), b[i].end());
// 4) Concatenate all buckets into arr[]
int index = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < b[i].size(); j++)
arr[index++] = b[i][j];
}
/* Driver program to test above function */
int main()
{
float arr[]
= { 0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434 };
int n = sizeof(arr) / sizeof(arr[0]);
bucketSort(arr, n);
cout << "Sorted array is \n";
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
Java
// Java program to sort an array
// using bucket sort
import java.util.*;
import java.util.Collections;
class GFG {
// Function to sort arr[] of size n
// using bucket sort
static void bucketSort(float arr[], int n)
{
if (n <= 0)
return;
// 1) Create n empty buckets
@SuppressWarnings("unchecked")
Vector[] buckets = new Vector[n];
for (int i = 0; i < n; i++) {
buckets[i] = new Vector();
}
// 2) Put array elements in different buckets
for (int i = 0; i < n; i++) {
float idx = arr[i] * n;
buckets[(int)idx].add(arr[i]);
}
// 3) Sort individual buckets
for (int i = 0; i < n; i++) {
Collections.sort(buckets[i]);
}
// 4) Concatenate all buckets into arr[]
int index = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < buckets[i].size(); j++) {
arr[index++] = buckets[i].get(j);
}
}
}
// Driver code
public static void main(String args[])
{
float arr[] = { (float)0.897, (float)0.565,
(float)0.656, (float)0.1234,
(float)0.665, (float)0.3434 };
int n = arr.length;
bucketSort(arr, n);
System.out.println("Sorted array is ");
for (float el : arr) {
System.out.print(el + " ");
}
}
}
// This code is contributed by Himangshu Shekhar Jha
Python3
# Python3 program to sort an array
# using bucket sort
def insertionSort(b):
for i in range(1, len(b)):
up = b[i]
j = i - 1
while j >= 0 and b[j] > up:
b[j + 1] = b[j]
j -= 1
b[j + 1] = up
return b
def bucketSort(x):
arr = []
slot_num = 10 # 10 means 10 slots, each
# slot's size is 0.1
for i in range(slot_num):
arr.append([])
# Put array elements in different buckets
for j in x:
index_b = int(slot_num * j)
arr[index_b].append(j)
# Sort individual buckets
for i in range(slot_num):
arr[i] = insertionSort(arr[i])
# concatenate the result
k = 0
for i in range(slot_num):
for j in range(len(arr[i])):
x[k] = arr[i][j]
k += 1
return x
# Driver Code
x = [0.897, 0.565, 0.656,
0.1234, 0.665, 0.3434]
print("Sorted Array is")
print(bucketSort(x))
# This code is contributed by
# Oneil Hsiao
C#
// C# program to sort an array
// using bucket sort
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
// Function to sort arr[] of size n
// using bucket sort
static void bucketSort(float []arr, int n)
{
if (n <= 0)
return;
// 1) Create n empty buckets
List[] buckets = new List[n];
for (int i = 0; i < n; i++) {
buckets[i] = new List();
}
// 2) Put array elements in different buckets
for (int i = 0; i < n; i++) {
float idx = arr[i] * n;
buckets[(int)idx].Add(arr[i]);
}
// 3) Sort individual buckets
for (int i = 0; i < n; i++) {
buckets[i].Sort();
}
// 4) Concatenate all buckets into arr[]
int index = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < buckets[i].Count; j++) {
arr[index++] = buckets[i][j];
}
}
}
// Driver code
public static void Main()
{
float []arr = { (float)0.897, (float)0.565,
(float)0.656, (float)0.1234,
(float)0.665, (float)0.3434 };
int n = arr.Length;
bucketSort(arr, n);
Console.WriteLine("Sorted array is ");
foreach(float el in arr) {
Console.Write(el + " ");
}
}
}
// This code is contributed by rutvik_56
Python3
# Python program for the above approach
# Bucket sort for numbers
# having interger part
def bucketSort(arr, noOfBuckets):
max_ele = max(arr)
min_ele = min(arr)
# range(for buckets)
rnge = (max_ele - min_ele) / noOfBuckets
temp = []
# create empty buckets
for i in range(noOfBuckets):
temp.append([])
# scatter the array elements
# into the correct bucket
for i in range(len(arr)):
diff = (arr[i] - min_ele) / rnge -
int((arr[i] - min_ele) / rnge)
# append the boundary elements to the lower array
if(diff == 0 and arr[i] != min_ele):
temp[int((arr[i] - min_ele) / rnge) - 1].append(arr[i])
else:
temp[int((arr[i] - min_ele) / rnge)].append(arr[i])
# Sort each bucket individually
for i in range(len(temp)):
if len(temp[i]) != 0:
temp[i].sort()
# Gather sorted elements
# to the original array
k = 0
for lst in temp:
if lst:
for i in lst:
arr[k] = i
k = k+1
# Driver Code
arr = [9.8, 0.6, 10.1, 1.9, 3.07, 3.04, 5.0, 8.0, 4.8, 7.68]
noOfBuckets = 5
bucketSort(arr, noOfBuckets)
print("Sorted array: ", arr)
# This code is contributed by
# Vinita Yadav
Sorted array is
0.1234 0.3434 0.565 0.656 0.665 0.897
桶对具有整数部分的数字进行排序:
算法:
- 查找数组的最大元素和最小个数
- 计算每个铲斗的范围
range = (max - min) / n
n is the number of buckets
3.创建计算范围的n个存储桶
4.将数组元素分散到这些存储桶中
BucketIndex = ( arr[i] - min ) / range
6.现在分别对每个存储桶进行排序
7.收集从存储桶到原始数组的排序元素
Input :
Unsorted array: [ 9.8 , 0.6 , 10.1 , 1.9 , 3.07 , 3.04 , 5.0 , 8.0 , 4.8 , 7.68 ]
No of buckets : 5
Output :
Sorted array: [ 0.6 , 1.9 , 3.04 , 3.07 , 4.8 , 5.0 , 7.68 , 8.0 , 9.8 , 10.1 ]
Input :
Unsorted array: [0.49 , 5.9 , 3.4 , 1.11 , 4.5 , 6.6 , 2.0]
No of buckets: 3
Output :
Sorted array: [0.49 , 1.11 , 2.0 , 3.4 , 4.5 , 5.9 , 6.6]
代码 :
Python3
# Python program for the above approach
# Bucket sort for numbers
# having interger part
def bucketSort(arr, noOfBuckets):
max_ele = max(arr)
min_ele = min(arr)
# range(for buckets)
rnge = (max_ele - min_ele) / noOfBuckets
temp = []
# create empty buckets
for i in range(noOfBuckets):
temp.append([])
# scatter the array elements
# into the correct bucket
for i in range(len(arr)):
diff = (arr[i] - min_ele) / rnge -
int((arr[i] - min_ele) / rnge)
# append the boundary elements to the lower array
if(diff == 0 and arr[i] != min_ele):
temp[int((arr[i] - min_ele) / rnge) - 1].append(arr[i])
else:
temp[int((arr[i] - min_ele) / rnge)].append(arr[i])
# Sort each bucket individually
for i in range(len(temp)):
if len(temp[i]) != 0:
temp[i].sort()
# Gather sorted elements
# to the original array
k = 0
for lst in temp:
if lst:
for i in lst:
arr[k] = i
k = k+1
# Driver Code
arr = [9.8, 0.6, 10.1, 1.9, 3.07, 3.04, 5.0, 8.0, 4.8, 7.68]
noOfBuckets = 5
bucketSort(arr, noOfBuckets)
print("Sorted array: ", arr)
# This code is contributed by
# Vinita Yadav
Sorted array: [0.6, 1.9, 3.04, 3.07, 4.8, 5.0, 7.68, 8.0, 9.8, 10.1]
存储桶排序以对带有负数的数组进行排序
参考:
算法入门第三版,作者:Clifford Stein,Thomas H. Cormen,Charles E. Leiserson,Ronald L. Rivest
http://en.wikipedia.org/wiki/Bucket_sort https://youtu.be/VuXbEb5ywrU
快照:
桶排序测验
GeeksforGeeks / GeeksQuiz上的其他排序算法:
- 选择排序
- 气泡排序
- 插入排序
- 合并排序
- 堆排序
- 快速排序
- 基数排序
- 计数排序
- 壳排序