-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBucketSort.cpp
More file actions
128 lines (101 loc) · 3.27 KB
/
BucketSort.cpp
File metadata and controls
128 lines (101 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "BucketSort.h"
#include <string>
#include <algorithm>
#include <cmath>
#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <sstream>
int getDigit(unsigned num,int d){ //get a digit of a number , d ranges from left(0) to right(9)
int n_digits = 1;
unsigned num_copy = num;
while(num_copy/10!=0){
n_digits++;
num_copy=num_copy/10;
}
if(d>=n_digits)return -1; //padding -1
int temp =1;
for (int i=0;i<n_digits-1-d;i++){temp*=10;}
return (num/temp)%10;
}
std::vector<unsigned int>* msdsort(std::vector<unsigned int>* numbersToSort,int pider){ //MSD redix sort using resursion
if((*numbersToSort).size()==0||(*numbersToSort).size()==1){
return numbersToSort;
}
std::vector <std::vector<unsigned int>> bins; //create bins
for (unsigned i = 0;i<11;i++){ // bins form #0 to #10 represent digit: -1,0,1,2,3,4,5,6,7,8,9
std::vector <unsigned int> digit_container;
bins.push_back(digit_container);
}
int digit ;
std::vector<unsigned int>* ContainerToSort; //container for all numbers to be sorted in a thread
ContainerToSort = numbersToSort;
//assign into bins
for (auto iter = (*ContainerToSort).begin();iter!=(*ContainerToSort).end();iter++){
auto num = *iter;
digit = getDigit(num,pider);
(bins[digit+1]).push_back(*iter);
}
(*ContainerToSort).clear();
pider++;
if (pider <=9){
for (int i=0;i<11;i++){// for each bin
auto newbin = msdsort(&(bins[i]),pider);//resursion
(bins[i]) = *newbin;
}
}
//collect numbers in bins
for(int i =0;i<11;i++){
auto thisbin = bins[i];
(*ContainerToSort).insert((*ContainerToSort).end(),thisbin.begin(),thisbin.end());
}
numbersToSort = ContainerToSort;
return ContainerToSort;
}
bool aLessB(const unsigned int& x, const unsigned int& y) { //Define less
if(x==y)return false;
for (int i=0;i<10;i++){
if(getDigit(x,i)<getDigit(y,i))return true;
if(getDigit(x,i)>getDigit(y,i))return false;
}
return false;
}
void BucketSort::sort(unsigned int numCores) {
const unsigned int Cores = std::thread::hardware_concurrency();
if (numCores>Cores){numCores = Cores;}//Examine number of cores
std::vector <std::vector<unsigned int>> inputs;// contains several buckets = number of threads
for (unsigned i = 0;i<numCores;i++){ //Create the buckets containing numbers
std::vector <unsigned int> newVector;
inputs.push_back(newVector);
}
//Devide all thr numbers to be sorted into buckets
int idx = 0;
for (auto iter = numbersToSort.begin();iter!=numbersToSort.end();iter++){
(inputs[idx%numCores]).push_back(*iter);
idx ++;
}
//MultiThreading
for (unsigned i = 0; i < numCores; i++) {
std::thread new_thread(msdsort,&(inputs[i]),0);
new_thread.join();
}
//Merge the results from multithreaded approach
std::vector <unsigned int> result;
int small_idx = 0;
unsigned int smallest = 999999999; //Maximum in this unsigned int case
while(result.size()<numbersToSort.size()){
small_idx = 0;
smallest = 999999999;
for (unsigned i = 0; i < numCores; i++) {
if((inputs[i]).size()==0){continue;}
if (aLessB( (inputs[i])[0] , smallest ) ){ //select the smallest one
small_idx = i;
smallest = (inputs[i])[0];
}
}
result.push_back(smallest);
(inputs[small_idx]).erase((inputs[small_idx]).begin());
}
numbersToSort = result;
}