Algorithme de tri de seau (Java, Python, C /C++ Exemples de codes)
Quโest-ce que le tri par seau ?
Le tri par compartiment, souvent appelรฉ tri par bac, est une mรฉthode de tri par comparaison qui accepte un tableau non triรฉ comme entrรฉe et produit en consรฉquence un tableau triรฉ. Cette mรฉthode fonctionne en distribuant les รฉlรฉments dans plusieurs compartiments et en triant chacun de ces compartiments individuellement par n'importe quel algorithme de tri tel que le tri par insertion. Ensuite, tous les compartiments sont fusionnรฉs pour former un tableau triรฉ.
Le tri par compartiment est couramment utilisรฉ lorsque les รฉlรฉments sont :
- Valeurs ร virgule flottante
- Uniformรฉment rรฉparti sur une plage
La complexitรฉ temporelle du tri par compartiments dรฉpend du nombre de compartiments utilisรฉs et de l'uniformitรฉ de la distribution des entrรฉes. Alors que diffรฉrents algorithmes de tri tels que sorte de coquille, fusionner le tri, le tri en tas et tri rapide peut atteindre la complexitรฉ temporelle dans le meilleur des cas de O(n*logn), l'algorithme de tri par compartiments peut atteindre la mรชme complexitรฉ temporelle linรฉaire ou O(n).
Le tri par compartiment suit l'approche scatter-gather. En appliquant cette approche, les รฉlรฉments sont dispersรฉs dans les compartiments correspondants, triรฉs dans les compartiments et rassemblรฉs pour former un tableau triรฉ lors de l'รฉtape finale. Cette approche scatter-gather est discutรฉe dans la section suivante
Approche Dispersion-Rassemblement
Des problรจmes complexes et ร grande รฉchelle peuvent parfois รชtre difficiles ร rรฉsoudre. L'approche scatter-gather tente de rรฉsoudre de tels problรจmes en divisant l'ensemble des donnรฉes en clusters. Ensuite, chaque cluster est abordรฉ sรฉparรฉment et le tout rassemblรฉ pour obtenir la rรฉponse finale.
Voici comment l'algorithme de tri par bucket implรฉmente la mรฉthode scatter-gather :
Comment fonctionne le tri par compartiment
Le principe de fonctionnement de base du tri par compartiments est le suivant :
- Un ensemble de compartiments vides est crรฉรฉ. En fonction des diffรฉrentes politiques, le nombre de compartiments peut diffรฉrer.
- ร partir du tableau d'entrรฉe, placez chaque รฉlรฉment dans son compartiment correspondant.
- Triez ces compartiments individuellement.
- Concatรฉnez les compartiments triรฉs pour crรฉer un seul tableau de sortie.
Les รฉtapes de travail dรฉtaillรฉes sont fournies dans les sections suivantes.
Pseudo 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
Mรฉthode 1 : algorithme de tri par compartiment pour la virgule flottante Numbers
L'algorithme de tri par compartiment pour les nombres ร virgule flottante compris entre 0.0 et 1.0 :
รtape 1) Crรฉez dix (10) compartiments vides de telle sorte que le premier compartiment contienne des nombres compris dans la plage [0.0, 0.1). Ensuite, le deuxiรจme compartiment contiendra [0.1, 0.2), et ainsi de suite.
รtape 2) Pour chaque รฉlรฉment du tableau :
-
un. Calculez l'indice de compartiment ร l'aide de la formule :
index du compartiment = no_of_buckets *array_element
-
b. Insรฉrez l'รฉlรฉment dans le bucket[bucket_index]
รtape 3) Triez chaque compartiment individuellement ร lโaide du tri par insertion.
รtape 4) Concatรฉnez tous les compartiments dans un seul tableau.
Voyons un exemple de tri par bucket. Pour cet exemple, nous allons trier le tableau suivant ร l'aide de l'algorithme de tri par compartiment :
รtape 1) Tout dโabord, nous allons crรฉer 10 buckets vides. Le premier compartiment contiendra les nombres compris entre [0.0, 0.1). Ensuite, le deuxiรจme compartiment contiendra les nombres compris entre [0.1, 0.2) et ainsi de suite.
รtape 2) Pour chaque รฉlรฉment du tableau, nous calculerons lโindex du bucket et placerons lโรฉlรฉment dans ce bucket.
L'indice de compartiment peut รชtre calculรฉ ร l'aide de la formule :
bucket_index= no_of_buckets*array_element
Calcul de l'indice de compartiment :
a) 0.78
bucket_index = no_of_buckets*array_element
= 10 * 0.78
= 7.8
Par consรฉquent, l'รฉlรฉment 0.78 sera stockรฉ sur le bucket[floor(7.8)] ou le bucket[7].
b) 0.17
bucket_index = no_of_buckets * รฉlรฉment du tableau
= 10 * 0.17
= 1.7
L'รฉlรฉment de tableau 0.17 sera stockรฉ sur bucket[floor(1.7)] ou bucket[1].
c) 0.39
bucket_index = no_of_buckets * รฉlรฉment du tableau
= 10 * 0.39
= 3.9
0.39 sera stockรฉ sur bucket[floor(3.9)] ou bucket[3].
Aprรจs avoir parcouru tous les รฉlรฉments du tableau, les buckets seront les suivants :
รtape 3) Ensuite, chaque compartiment sera triรฉ ร lโaide du tri par insertion. Aprรจs l'opรฉration de tri, le rรฉsultat serait :
รtape 4) Dans la derniรจre รฉtape, les buckets seront concatรฉnรฉs en un seul tableau. Ce tableau sera le rรฉsultat triรฉ de lโentrรฉe.
Chaque bucket sera concatรฉnรฉ au tableau de sortie. Par exemple, la concatรฉnation des รฉlรฉments du deuxiรจme bucket :
La concatรฉnation des derniers รฉlรฉments du bucket sera la suivante :
Aprรจs concatรฉnation, le tableau rรฉsultant sera le tableau triรฉ souhaitรฉ.
Programme de tri de seaux en C/C++
Entrรฉes :
//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;
}
Sortie :
Sorted Output: 0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94
Programme de tri par seau dans Python
Entrรฉes :
# 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))
Sortie :
Sorted Output: [0.12, 0.17, 0.21, 0.23, 0.26, 0.39, 0.69, 0.72, 0.78, 0.94]
Seau Trier dans Java
Entrรฉes :
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]+" ");
}
}
}
Sortie :
Sorted Output: 0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94
Mรฉthode 2 : algorithme de tri par compartiment pour les รฉlรฉments entiers
L'algorithme de tri par compartiment pour l'entrรฉe contenant des nombres au-delร de la plage [0.0, 1.0] est un peu diffรฉrent du prรฉcรฉdent. algorithme. Les รฉtapes requises pour ce cas sont les suivantes :
รtape 1) Trouvez les รฉlรฉments maximum et minimum.
รtape 2) Sรฉlectionnez le nombre de compartiments, n, et initialisez ces compartiments comme รฉtant vides.
รtape 3) Calculez la plage ou la portรฉe de chaque compartiment ร l'aide de la formule :
span = (maximum - minimum)/n
รtape 4) Pour chaque รฉlรฉment du tableau :
-
1.Calculer l'indice du bucket :
bucket_index = (element - minimum)/span-
2.Insรฉrez l'รฉlรฉment dans le bucket[bucket_index]
รtape 5) Triez chaque compartiment ร lโaide du tri par insertion.
รtape 6) Concatรฉnez tous les compartiments dans un seul tableau.
Voyons un exemple de cet algorithme de tri par compartiment. Pour cet exemple, nous allons trier le tableau suivant ร l'aide de l'algorithme de tri par compartiment :
รtape 1) Dans la premiรจre รฉtape, les รฉlรฉments maximum et minimum du tableau donnรฉ doivent รชtre trouvรฉs. Pour cet exemple, le maximum est 24 et le minimum est 1.
รtape 2) Maintenant, nous devons sรฉlectionner un nombre de compartiments vides, n. Dans cet exemple, nous prendrons 5 seaux. Ensuite nous les initialiserons comme vides.
รtape 3) La portรฉe de chaque compartiment doit รชtre calculรฉe ร l'aide de la formule suivante :
span = (maximum-minimum)/n = (24-1)/5 = 4;
Par consรฉquent, le premier compartiment contiendra les nombres compris dans la plage [0, 5). Le deuxiรจme compartiment contiendra les nombres compris entre [5, 10) et ainsi de suite.
รtape 4) Pour chaque รฉlรฉment du tableau, nous calculerons lโindex du bucket et placerons lโรฉlรฉment dans ce bucket. L'indice de compartiment peut รชtre calculรฉ ร l'aide de la formule :
bucket_index = (element - minimum)/span
Calcul de l'indice de compartiment :
-
a) 11bucket_index = (รฉlรฉment โ โโminimum)/span
=(11 1-4 )/
=2
Ainsi, l'รฉlรฉment 11 sera stockรฉ dans bucket[2].
-
b) 9
bucket_index = (รฉlรฉment โ โโminimum)/span
=(9 1-4 )/
=2
Note: Comme 9 est un รฉlรฉment de limite pour le bucket[1], il doit รชtre ajoutรฉ dans bucket[1] au lieu d'รชtre ajoutรฉ dans le mรชme bucket de l'รฉlรฉment prรฉcรฉdent.
Aprรจs avoir effectuรฉ les opรฉrations pour chaque รฉlรฉment, les buckets seront les suivants :
รtape 5) Dรฉsormais, chaque compartiment sera triรฉ ร lโaide du tri par insertion. Les seaux aprรจs tri-
รtape 6) Dans la derniรจre รฉtape, les buckets seront concatรฉnรฉs en un seul tableau. Que tableau sera le rรฉsultat triรฉ de lโentrรฉe.
Programme de tri de seaux en C/C++
Entrรฉes :
#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;
}
Sortie :
Sorted Output:1 8 9 11 12 13 17 19 21 24
Programme de tri par seau dans Python
Entrรฉes :
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)
Sortie :
Sorted Output: [1, 8, 9, 11, 12, 13, 17, 19, 21, 24]
Seau Trier dans Java
Entrรฉes :
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 + " ");
}
}
}
Sortie :
Sorted Output: 1.0 8.0 9.0 11.0 12.0 13.0 17.0 19.0 21.0 24.0
Avantages et inconvรฉnients
| Avantages | Inconvรฉnients |
|---|---|
| Effectuer un calcul plus rapide | Consomme plus d'espace par rapport aux autres algorithmes |
| Il peut รชtre utilisรฉ comme mรฉthode de tri externe | Fonctionne mal lorsque les donnรฉes ne sont pas uniformรฉment rรฉparties |
| Les seaux peuvent รชtre traitรฉs indรฉpendamment |
Analyse de la complexitรฉ du tri par compartiment
Complexitรฉ temporelle du tri par seau
- Meilleur cas de complexitรฉ :Si tous les รฉlรฉments du tableau sont uniformรฉment distribuรฉs et triรฉs au prรฉalable, il faudrait un temps O(n) pour disperser les รฉlรฉments dans les compartiments correspondants. Triez ensuite chaque seau en utilisant tri par insertion coรปterait O(k). Ainsi, la complexitรฉ globale serait O(n+k).
- Complexitรฉ moyenne des cas :Pour les cas moyens, nous supposons que les entrรฉes sont uniformรฉment distribuรฉes. Ainsi, l'algorithme de tri par compartiment atteint une complexitรฉ temporelle linรฉaire de O (n + k). Ici, un temps O(n) est nรฉcessaire pour disperser les รฉlรฉments et un temps O(k) est nรฉcessaire pour trier ces รฉlรฉments ร l'aide du tri par insertion.
- Pire complexitรฉ des cas :Dans le pire des cas, les รฉlรฉments ne seront pas uniformรฉment rรฉpartis et concentrรฉs sur un ou deux seaux spรฉcifiques. Dans ce cas, le tri par compartiment fonctionnera comme un algorithme de tri ร bulles. Par consรฉquent, dans le pire des cas, la complexitรฉ temporelle dโun tri par compartiment serait O(n^2).
Complexitรฉ spatiale du tri par seau
La complexitรฉ spatiale du tri par compartiment est O(n*k). Ici n est le nombre d'รฉlรฉments et k est le nombre de compartiments requis.


















