Algoritme for bøttesortering (Java, Python, C/C++ Kodeeksempler)
Hva er Bucket Sort?
Bøttesortering, ofte kalt bin-sortering, er en sammenligningssorteringsmetode som aksepterer en usortert matrise som input og produserer en sortert matrise som et resultat. Denne metoden fungerer ved å distribuere elementene i flere bøtter og sortere hver av disse bøttene individuelt ved hjelp av en hvilken som helst sorteringsalgoritme, for eksempel innsettingssortering. Deretter slås alle bøttene sammen for å danne en sortert matrise.
Bøttesortering brukes ofte når elementene er-
- Flytende kommaverdier
- Jevnt fordelt over et område
Tidskompleksiteten til bøttesortering avhenger av antall bøtter som brukes og enhetligheten i inputfordelingen. Mens ulike sorteringsalgoritmer som f.eks skjell sortering, slå sammen sortering, heapsort og Quicksort kan oppnå best-case tidskompleksiteten til O(n*logn), kan bøttesorteringsalgoritmen oppnå det samme i lineær tidskompleksitet eller O(n).
Bøttesortering følger scatter-samler-tilnærmingen. Ved å bruke denne tilnærmingen blir elementene spredt i de tilsvarende bøttene, sortert i bøttene og samlet for å danne en sortert matrise som det siste trinnet. Denne scatter-samler-tilnærmingen diskuteres i den følgende delen
Scatter-Gather-Approach
Store, komplekse problemer kan av og til være utfordrende å løse. Scatter-gather-tilnærmingen forsøker å løse slike problemer ved å dele opp hele datasettet i klynger. Deretter blir hver klynge adressert separat og samlet alt sammen igjen for å få det endelige svaret.
Dette er hvordan bøttesorteringsalgoritmen implementerer scatter-gather-metoden:
Hvordan bøttesortering fungerer
Det grunnleggende arbeidsprinsippet for bøttesortering er som følger:
- Et sett med tomme bøtter opprettes. Basert på ulike retningslinjer, kan antall bøtter variere.
- Fra input-arrayet legger du hvert element i den tilhørende bøtten.
- Sorter disse bøttene individuelt.
- Sammenslå de sorterte bøttene for å lage en enkelt utmatrise.
De detaljerte arbeidstrinnene er gitt i de følgende avsnittene.
Pseudokode
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
Metode 1: Bøttesorteringsalgoritme for flytende punkt Numbers
Bøttesorteringsalgoritmen for flyttall i området fra 0.0 til 1.0:
Trinn 1) Opprett ti(10) tomme bøtter slik at den første bøtten vil inneholde tall innenfor området [0.0, 0.1). Da vil den andre bøtten inneholde innenfor [0.1, 0.2), og så videre.
Trinn 2) For hvert array-element:
-
en. Beregn bøtteindeksen ved å bruke formelen:
bøtteindeks= no_of_buckets *array_element
-
b. Sett elementet inn i bøtte[bucket_index]
Trinn 3) Sorter hver bøtte individuelt ved hjelp av innsettingssortering.
Trinn 4) Slå sammen alle bøttene i en enkelt matrise.
La oss se et eksempel på bøttesortering. For dette eksemplet vil vi sortere følgende matrise ved å bruke bøttesorteringsalgoritmen-
Trinn 1) Først skal vi lage 10 tomme bøtter. Den første bøtten vil inneholde tallene mellom [0.0, 0.1). Da vil den andre bøtten inneholde tallene mellom [0.1, 0.2) og så videre.
Trinn 2) For hvert array-element vil vi beregne bøtteindeksen og plassere elementet i den bøtten.
Bøtteindeksen kan beregnes ved hjelp av formelen:
bucket_index= no_of_buckets*array_element
Beregning av bøtteindeks:
a) 0.78
bøtteindeks = no_of_buckets*array_element
= 10 * 0.78
= 7.8
Derfor vil elementet 0.78 lagres på bøtte[gulv(7.8)] eller bøtte[7].
b) 0.17
bucket_index = no_of_buckets * matriseelement
= 10 * 0.17
= 1.7
Array-elementet 0.17 vil bli lagret på bøtte[gulv(1.7)] eller bøtte[1].
0.39
bucket_index = no_of_buckets * matriseelement
= 10*0.39
= 3.9
0.39 vil bli lagret på bøtte[gulv(3.9)] eller bøtte[3].
Etter å ha iterert over alle array-elementer, vil bøttene være følgende:
Trinn 3) Deretter vil hver bøtte sorteres ved hjelp av innsettingssortering. Etter sorteringsoperasjonen vil utgangen være:
Trinn 4) I det siste trinnet vil bøttene settes sammen til en enkelt matrise. Denne matrisen vil være det sorterte resultatet av input.
Hver bøtte vil bli koblet sammen til utdatamatrisen. For eksempel - sammenkoblingen av de andre bøtteelementene:
Sammenkoblingen av de siste bøtteelementene vil være følgende:
Etter sammenkobling vil den resulterende matrisen være den ønskede sorterte matrisen.
Bøttesorteringsprogram i C/C++
Inngang:
//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; }
Utgang:
Sorted Output: 0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94
Bøttesorteringsprogram inn Python
Inngang:
# 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))
Utgang:
Sorted Output: [0.12, 0.17, 0.21, 0.23, 0.26, 0.39, 0.69, 0.72, 0.78, 0.94]
Bøtte Sorter inn Java
Inngang:
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]+" "); } } }
Utgang:
Sorted Output: 0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94
Metode 2: Bucket Sort Algoritme for heltallselementer
Bundsorteringsalgoritmen for inngangen som inneholder tall utenfor området [0.0, 1.0] er litt annerledes enn den forrige algoritme. Trinnene som kreves for denne saken er som følger-
Trinn 1) Finn maksimums- og minimumselementene.
Trinn 2) Velg antall bøtte, n, og initialiser disse bøttene som tomme.
Trinn 3) Beregn rekkevidden eller spennvidden til hver bøtte ved å bruke formelen:
span = (maximum - minimum)/n
Trinn 4) For hvert array-element:
-
1. Beregn bøtteindeks:
bucket_index = (element - minimum)/span
-
2. Sett inn elementet i bøtte[bøtte_indeks]
Trinn 5) Sorter hver bøtte ved hjelp av innsettingssortering.
Trinn 6) Sett sammen alle bøttene i en enkelt matrise.
La oss se et eksempel på denne bøttesorteringsalgoritmen. For dette eksemplet vil vi sortere følgende matrise ved å bruke bøttesorteringsalgoritmen-
Trinn 1) I det første trinnet må maksimums- og minimumselementene til den gitte matrisen finnes. For dette eksemplet er maksimum 24 og minimum er 1.
Trinn 2) Nå må vi velge et antall tomme bøtter, n. I dette eksemplet tar vi 5 bøtter. Deretter vil vi initialisere dem som tomme.
Trinn 3) Spennvidden til hver bøtte må beregnes ved hjelp av følgende formel:
span = (maximum-minimum)/n = (24-1)/5 = 4
;
Derfor vil den første bøtten inneholde tallene innenfor området [0, 5). Den andre bøtten vil inneholde tallene innenfor [5, 10) og så videre.
Trinn 4) For hvert array-element vil vi beregne bøtteindeksen og plassere elementet i den bøtten. Bøtteindeksen kan beregnes ved hjelp av formelen:
bucket_index = (element - minimum)/span
Beregning av bøtteindeks:
-
a) 11bucket_index = (element – minimum)/spenn
=(11-1)/4
=2
Dermed vil element 11 bli lagret i bøtte[2].
-
b) 9
bøtteindeks = (element – minimum)/spenn
=(9-1)/4
=2
OBS: Siden 9 er et grenseelement for bøtte[1], må det legges til i bøtte[1] i stedet for å legge til i samme bøtte som det forrige elementet.
Etter å ha utført operasjonene for hvert element, vil bøttene være som følger:
Trinn 5) Nå vil hver bøtte sorteres ved hjelp av innsettingssortering. Bøttene etter sortering-
Trinn 6) I det siste trinnet vil bøttene settes sammen til en enkelt matrise. At matrise vil være det sorterte resultatet av innspillet.
Bøttesorteringsprogram i C/C++
Inngang:
#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; }
Utgang:
Sorted Output:1 8 9 11 12 13 17 19 21 24
Bøttesorteringsprogram inn Python
Inngang:
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)
Utgang:
Sorted Output: [1, 8, 9, 11, 12, 13, 17, 19, 21, 24]
Bøtte Sorter inn Java
Inngang:
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 + " "); } } }
Utgang:
Sorted Output: 1.0 8.0 9.0 11.0 12.0 13.0 17.0 19.0 21.0 24.0
Argumenter for og imot
Pros | Ulemper |
---|---|
Utfør raskere beregning | Bruker mer plass sammenlignet med andre algoritmer |
Den kan brukes som ekstern sorteringsmetode | Yter dårlig når dataene ikke er jevnt fordelt |
Bøtter kan behandles uavhengig |
Bøttesortering kompleksitetsanalyse
Bøttesortering sin tidskompleksitet
- Beste sakskompleksitet:Hvis alle array-elementene er jevnt fordelt og sortert på forhånd, vil det kreve O(n) tid å spre elementene i de tilsvarende bøttene. Deretter sorterer du hver bøtte ved hjelp av innsettings sortering ville koste O(k). Dermed vil den totale kompleksiteten være O(n+k).
- Gjennomsnittlig sakskompleksitet:For gjennomsnittlige tilfeller antar vi at inngangene er jevnt fordelt. Dermed oppnår bøttesorteringsalgoritmen lineær tidskompleksitet på O(n+k). Her kreves O(n)-tid for å spre elementene og O(k)-tid kreves for å sortere disse elementene ved å bruke innsettingssortering.
- Worst Case Complexity:I verste fall vil ikke elementene være jevnt fordelt og konsentrert over en eller to spesifikke bøtter. I så fall vil bøttesortering fungere som en boblesorteringsalgoritme. Derfor, i verste fall, vil tidskompleksiteten til en bøttesortering være O(n^2).
Plasskompleksiteten til bøttesortering
Bøttesorteringens plasskompleksitet er O(n*k). Her er n antall elementer og k er antall bøtter som kreves.