Bucket Sort Algorithm (Java, Python, C/C++ Kodexempel)

Vad är Bucket Sort?

Skogsortering, ofta kallad lagersortering, är en jämförelsesorteringsmetod som accepterar en osorterad matris som en indata och producerar en sorterad matris som ett resultat. Den här metoden fungerar genom att dela upp elementen i flera hinkar och sortera var och en av dessa hinkar individuellt med valfri sorteringsalgoritm, såsom infogningssortering. Sedan slås alla hinkar samman för att bilda en sorterad array.

Skopsortering används vanligtvis när elementen är-

  1. Flyttalsvärden
  2. Jämnt fördelad över ett intervall

Skopsorteringens tidskomplexitet beror på antalet använda hinkar och enhetligheten i inmatningsfördelningen. Medan olika sorteringsalgoritmer som t.ex skal sortera, slå samman sortering, heapsortera och quick kan uppnå bästa möjliga tidskomplexitet för O(n*logn), kan skopsorteringsalgoritmen uppnå samma i linjär tidskomplexitet eller O(n).

Hinksortering följer scatter-gather-metoden. Genom att tillämpa detta tillvägagångssätt sprids elementen i motsvarande hinkar, sorteras i hinkarna och samlas för att bilda en sorterad array som det sista steget. Denna scatter-insamlingsmetod diskuteras i följande avsnitt

Scatter-Gather-Approach

Storskaliga, komplexa problem kan ibland vara utmanande att lösa. Scatter-gather-metoden försöker lösa sådana problem genom att dela upp hela datamängden i kluster. Sedan adresseras varje kluster separat och sammanförs allt för att få det slutgiltiga svaret.

Så här implementerar bucketsorteringsalgoritmen scatter-gather-metoden:

Scatter-Gather-Approach

Hur hinksortering fungerar

Den grundläggande arbetsprincipen för skopsortering är följande:

  1. En uppsättning tomma hinkar skapas. Baserat på olika policyer kan antalet hinkar variera.
  2. Från inmatningsmatrisen lägger du varje element i dess motsvarande hink.
  3. Sortera hinkarna individuellt.
  4. Sammanfoga de sorterade hinkarna för att skapa en enda utmatningsmatris.

De detaljerade arbetsstegen finns i följande avsnitt.

Pseudokod

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

Metod 1: Skopsorteringsalgoritm för flytande punkt Numbers

Skoksorteringsalgoritmen för flyttalsnummer inom intervallet 0.0 till 1.0:

Steg 1) Skapa tio(10) tomma hinkar så att den första hinken kommer att innehålla siffror inom intervallet [0.0, 0.1). Sedan kommer den andra hinken att innehålla inom [0.1, 0.2) och så vidare.

Steg 2) För varje arrayelement:

      a. Beräkna hinkindex med formeln:
      bucket index= no_of_buckets *array_element
      b. Sätt in elementet i hinken[bucket_index]

Steg 3) Sortera varje hink individuellt med hjälp av instickssortering.

Steg 4) Sammanfoga alla hinkar till en enda array.

Låt oss se ett exempel på en hinksortering. För det här exemplet kommer vi att sortera följande array med hjälp av hinksorteringsalgoritmen-

Skopsorteringsalgoritm för flytande punkt Numbers

Steg 1) Först skapar vi 10 tomma hinkar. Den första hinken kommer att innehålla siffrorna mellan [0.0, 0.1). Sedan kommer den andra hinken att innehålla siffrorna mellan [0.1, 0.2) och så vidare.

Skopsorteringsalgoritm för flytande punkt Numbers

Steg 2) För varje matriselement kommer vi att beräkna hinkindexet och placera elementet i den hinken.

Hinkindexet kan beräknas med formeln:
              bucket_index= no_of_buckets*array_element

Beräkning av hinkindex:
a) 0.78
      bucket_index = no_of_buckets*array_element
                   = 10 * 0.78
                   = 7.8
Därför kommer elementet 0.78 att lagras på hinken[golv(7.8)] eller hinken[7].

Skopsorteringsalgoritm för flytande punkt Numbers

b) 0.17
      bucket_index = no_of_buckets * matriselement
                   = 10 * 0.17
                   = 1.7

Arrayelementet 0.17 kommer att lagras på hink[golv(1.7)] eller hink[1].

Skopsorteringsalgoritm för flytande punkt Numbers

c) 0.39
      bucket_index = no_of_buckets * matriselement
                   = 10*0.39
                   = 3.9
   0.39 kommer att lagras på hink[golv(3.9)] eller hink[3].

Skopsorteringsalgoritm för flytande punkt Numbers

Efter att ha itererat över alla arrayelement kommer hinkarna att vara följande:

Skopsorteringsalgoritm för flytande punkt Numbers

Steg 3) Sedan kommer varje hink att sorteras med hjälp av insättningssortering. Efter sorteringsoperationen skulle resultatet bli:

Skopsorteringsalgoritm för flytande punkt Numbers

Steg 4) I det sista steget kommer hinkarna att sammanfogas till en enda array. Den matrisen kommer att vara det sorterade resultatet av inmatningen.

Varje hink kommer att kopplas samman till utmatningsmatrisen. Till exempel - sammanlänkningen av de andra hinkelementen:

Skopsorteringsalgoritm för flytande punkt Numbers

Sammansättningen av de sista hinkelementen kommer att vara följande:

Skopsorteringsalgoritm för flytande punkt Numbers

Efter sammanfogning kommer den resulterande arrayen att vara den önskade sorterade arrayen.

Skopsorteringsalgoritm för flytande punkt Numbers

Skopsorteringsprogram i C/C++

Ingång:

//Bucket Sort Program in C/C++
//For not having 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: \n";
 for (int i = 0; i< array_size; i++)
 cout<<input[i]<<" ";
return 0;
}

Produktion:

Sorted Output:
0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94

Hinksorteringsprogram in Python

Ingång:

# Bucket Sort Program in Python
# For not having 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))

Produktion:

Sorted Output:
[0.12, 0.17, 0.21, 0.23, 0.26, 0.39, 0.69, 0.72, 0.78, 0.94]

Hink Sortera in Java

Ingång:

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]+" ");
        }
    }
}

Produktion:

Sorted Output:
0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94

Metod 2: Bucket Sort Algoritm för heltalselement

Bucketsorteringsalgoritmen för indata som innehåller siffror utanför intervallet [0.0, 1.0] är lite annorlunda än den föregående algoritm. De steg som krävs för detta fall är följande-

Steg 1) Hitta de högsta och lägsta elementen.

Steg 2) Välj antalet hinkar, n, och initiera dessa hinkar som tomma.

Steg 3) Beräkna intervallet eller spännvidden för varje hink med hjälp av formeln:
               span = (maximum - minimum)/n

Steg 4) För varje arrayelement:

    1. Beräkna hinkindex:
                   bucket_index = (element - minimum)/span
    2.Sätt in elementet i hink[bucket_index]

Steg 5) Sortera varje hink med hjälp av insättningssortering.

Steg 6) Sammanfoga alla hinkar till en enda array.

Låt oss se ett exempel på denna hinksortering. För det här exemplet kommer vi att sortera följande array med hjälp av hinksorteringsalgoritmen-

Bucket Sort Algoritm för heltalselement

Steg 1) I det första steget måste maximi- och minimumelementen för den givna arrayen hittas. I det här exemplet är maxvärdet 24 och minimum 1.

Steg 2) Nu måste vi välja ett antal tomma hinkar, n. I det här exemplet tar vi 5 hinkar. Sedan initierar vi dem som tomma.

Steg 3) Spännvidden för varje hink måste beräknas med följande formel:
               span = (maximum-minimum)/n = (24-1)/5 = 4;

Därför kommer den första hinken att innehålla siffrorna inom intervallet [0, 5). Den andra hinken kommer att innehålla siffrorna inom [5, 10) och så vidare.

Bucket Sort Algoritm för heltalselement

Steg 4) För varje matriselement kommer vi att beräkna hinkindexet och placera elementet i den hinken. Hinkindexet kan beräknas med formeln:
               bucket_index = (element - minimum)/span

Beräkning av hinkindex:

    a) 11bucket_index = (element – ​​minimum)/span
                       =(11-1)/4
                       =2

Således kommer element 11 att lagras i hink[2].

Bucket Sort Algoritm för heltalselement

    b) 9
    bucket_index = (element – ​​minimum)/span
                       =(9-1)/4
                       =2

Obs: Eftersom 9 är ett gränselement för hinken[1], måste den läggas till i hinken[1] istället för att läggas till i samma hink som föregående element.

Bucket Sort Algoritm för heltalselement

Efter att ha utfört operationerna för varje element kommer hinkarna att se ut som följer:

Bucket Sort Algoritm för heltalselement

Steg 5) Nu kommer varje hink att sorteras med hjälp av insättningssortering. Hinkarna efter sortering-

Bucket Sort Algoritm för heltalselement

Steg 6) I det sista steget kommer hinkarna att sammanfogas till en enda array. Den där array kommer att vara det sorterade resultatet av inmatningen.

Bucket Sort Algoritm för heltalselement

Skopsorteringsprogram i C/C++

Ingång:

#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; i < input.size(); i++)
    cout <<input[i]<<" ";
  return 0;
}

Produktion:

Sorted Output:1 8 9 11 12 13 17 19 21 24

Hinksorteringsprogram in Python

Ingång:

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:\n", input)

Produktion:

Sorted Output:
[1, 8, 9, 11, 12, 13, 17, 19, 21, 24]

Hink Sortera in Java

Ingång:

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 + " ");
        }
    }
}

Produktion:

Sorted Output:
1.0 8.0 9.0 11.0 12.0 13.0 17.0 19.0 21.0 24.0

Fördelar nackdelar

Fördelar Nackdelar
Utför snabbare beräkningar Tar mer utrymme jämfört med andra algoritmer
Den kan användas som en extern sorteringsmetod Presterar dåligt när data inte är jämnt fördelad
Skopor kan bearbetas oberoende

Skopsorteringskomplexitetsanalys

Bucket Sorts tidskomplexitet

  • Best Case-komplexitet:Om alla arrayelementen är jämnt fördelade och sorterade i förväg, skulle det kräva O(n) tid för att sprida elementen i motsvarande hinkar. Sortera sedan varje hink med hjälp av insättningssortering skulle kosta O(k). Sålunda skulle den totala komplexiteten vara O(n+k).
  • Genomsnittlig ärendekomplexitet:För genomsnittliga fall antar vi att indata är likformigt fördelade. Sålunda uppnår skopsorteringsalgoritmen linjär tidskomplexitet O(n+k). Här krävs O(n)-tid för att sprida elementen och O(k)-tid krävs för att sortera dessa element med hjälp av infogningssortering.
  • Worst Case Complexity:I värsta fall kommer elementen inte att vara jämnt fördelade och koncentrerade över en eller två specifika hinkar. I så fall kommer hinksortering att fungera som en bubbelsorteringsalgoritm. Därför skulle tidskomplexiteten för en hinksortering i värsta fall vara O(n^2).

Utrymmeskomplexitet för hinksortering

Skoksortens rymdkomplexitet är O(n*k). Här är n antalet element och k är antalet hinkar som krävs.