📜  桶分类

📅  最后修改于: 2021-05-07 01:22:25             🧑  作者: Mango

当输入在一个范围内均匀分布时,存储桶排序主要有用。例如对于请考虑以下问题。
对一大组浮点数进行排序,这些浮点数的范围从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 

桶对具有整数部分的数字进行排序:

算法

  1. 查找数组的最大元素和最小个数
  2. 计算每个铲斗的范围
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
快照:

场景00505scene01009场景01513scene01729scene01801scene01945scene02017场景02521

桶排序测验

GeeksforGeeks / GeeksQuiz上的其他排序算法:

  • 选择排序
  • 气泡排序
  • 插入排序
  • 合并排序
  • 堆排序
  • 快速排序
  • 基数排序
  • 计数排序
  • 壳排序