Skip to content

Commit 3a7f20d

Browse files
committed
Small tweaks to the text
1 parent a3164f8 commit 3a7f20d

File tree

3 files changed

+131
-125
lines changed

3 files changed

+131
-125
lines changed

Bucket Sort/BucketSort.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import Foundation
2828

2929

3030
/**
31-
Perform buckets srot algorithm on the given input elements.
31+
Performs bucket sort algorithm on the given input elements.
3232
[Bucket Sort Algorithm Reference](https://en.wikipedia.org/wiki/Bucket_sort)
3333

3434
- Parameter elements: Array of Sortable elements

Bucket Sort/README.markdown

+129-123
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
# Bucket Sort
22

3-
[Bucket Sort or Bin Sort](https://en.wikipedia.org/wiki/Bucket_sort) is a distributed sorting algorithm, which sort elements from an array by performing these steps:
3+
Bucket Sort, also known as Bin Sort, is a distributed sorting algorithm, which sort elements from an array by performing these steps:
44

55
1) Distribute the elements into buckets or bins.
66
2) Sort each bucket individually.
7-
3) Merge the buckets in order to produce a sort array as results.
8-
7+
3) Merge the buckets in order to produce a sorted array as the result.
98

109
See the algorithm in action [here](https://www.cs.usfca.edu/~galles/visualization/BucketSort.html) and [here](http://www.algostructure.com/sorting/bucketsort.php).
1110

12-
1311
The performance for execution time is:
1412

1513
| Case | Performance |
@@ -18,11 +16,11 @@ The performance for execution time is:
1816
| Best | Omega(n + k) |
1917
| Average | Theta(n + k) |
2018

21-
Where **n** = #elements and **k** = #buckets
19+
Where **n** = the number of elements and **k** is the number of buckets.
2220

23-
On the **best case** the algorithm distributes the elements uniformily between buckets, a few elements are placed on each bucket and sorting the buckets is *O(1)*. Rearranging the elements is one more run through the initial list.
24-
On the **worst case** the elements are sent all to the same bucket, making the process takes *O(n^2)*.
21+
In the *best case*, the algorithm distributes the elements uniformily between buckets, a few elements are placed on each bucket and sorting the buckets is **O(1)**. Rearranging the elements is one more run through the initial list.
2522

23+
In the *worst case*, the elements are sent all to the same bucket, making the process take **O(n^2)**.
2624

2725
## Pseudocode
2826

@@ -39,22 +37,22 @@ A [pseudocode](https://en.wikipedia.org/wiki/Bucket_sort#Pseudocode) of the algo
3937

4038
## Graphically explained
4139

42-
###Distribute elements in buckets
40+
1) Distribute elements in buckets:
4341

4442
![distribution step](https://upload.wikimedia.org/wikipedia/commons/6/61/Bucket_sort_1.png)
4543

46-
###Sorting inside every bucket and merging
44+
2) Sorting inside every bucket and merging:
4745

4846
![sorting each bucket and merge](https://upload.wikimedia.org/wikipedia/commons/3/39/Bucket_sort_2.png)
4947

50-
##An example
48+
## An example
5149

5250
### Input
5351

54-
Suppose we have the following list of elements: `[2, 56, 4, 77, 26, 98, 55]`.
55-
And we define 10 buckets will be used. To determine the capacity of each bucket we need to know the `maximum element value`, in this case `98`.
52+
Suppose we have the following list of elements: `[2, 56, 4, 77, 26, 98, 55]`. Let's use 10 buckets. To determine the capacity of each bucket we need to know the *maximum element value*, in this case `98`.
5653

5754
So the buckets are:
55+
5856
* `bucket 1`: from 0 to 9
5957
* `bucket 2`: from 10 to 19
6058
* `bucket 3`: from 20 to 29
@@ -64,10 +62,11 @@ So the buckets are:
6462

6563
Now we need to choose a distribution function.
6664

67-
`bucketNumber = ( elementValue / totalNumberOfBuckets) + 1`
65+
`bucketNumber = (elementValue / totalNumberOfBuckets) + 1`
6866

69-
Such that applying that function we distribute all the elements in the buckets.
70-
In our example it is like following:
67+
Such that by applying that function we distribute all the elements in the buckets.
68+
69+
In our example it is like the following:
7170

7271
1. Apply the distribution function to `2`. `bucketNumber = (2 / 10) + 1 = 1`
7372
2. Apply the distribution function to `56`. `bucketNumber = (56 / 10) + 1 = 6`
@@ -99,155 +98,162 @@ Finally we go through all the buckets and put the elements back in the list:
9998
`[2, 4, 26, 55, 56, 77, 98]`
10099

101100

101+
## Swift implementation
102102

103-
##Swift implementation
103+
Here is a diagram that shows the functions, data structures and protocols for our bucker sort implementation:
104104

105-
###Classes
105+
![classes](Docs/BucketSort.png)
106106

107-
![classes](https://github.com/barbaramartina/swift-algorithm-club/blob/BucketSort/Bucket%20Sort/Docs/BucketSort.png)
107+
#### Main function
108108

109-
###Code
109+
`bucketSort()` is a generic function that can apply the algorithm to any element of type `T`, as long as `T` is `Sortable`.
110110

111-
Bucket Sort implementation use the following functions, data structures and protocols:
111+
```swift
112+
public func bucketSort<T:Sortable>(elements: [T],
113+
distributor: Distributor,
114+
sorter: Sorter,
115+
buckets: [Bucket<T>]) -> [T] {
116+
precondition(allPositiveNumbers(elements))
117+
precondition(enoughSpaceInBuckets(buckets, elements: elements))
112118

113-
####Main function
119+
var bucketsCopy = buckets
120+
for elem in elements {
121+
distributor.distribute(elem, buckets: &bucketsCopy)
122+
}
114123

115-
`bucketSort` is a generic function that can apply the algorithm to any element of type T, as long as T is Sortable.
124+
var results = [T]()
116125

117-
public func bucketSort<T:Sortable>(elements: [T], distributor: Distributor,sorter: Sorter, buckets: [Bucket<T>]) -> [T] {
118-
precondition(allPositiveNumbers(elements))
119-
precondition(enoughSpaceInBuckets(buckets, elements: elements))
120-
121-
var bucketsCopy = buckets
122-
for elem in elements {
123-
distributor.distribute(elem, buckets: &bucketsCopy)
124-
}
125-
126-
var results = [T]()
127-
128-
for bucket in bucketsCopy {
129-
results += bucket.sort(sorter)
130-
}
131-
132-
return results
133-
}
126+
for bucket in bucketsCopy {
127+
results += bucket.sort(sorter)
128+
}
134129

130+
return results
131+
}
132+
```
135133

136-
####Bucket
134+
#### Bucket
137135

138-
public struct Bucket<T:Sortable> {
139-
var elements: [T]
140-
let capacity: Int
141-
142-
public init(capacity: Int) {
143-
self.capacity = capacity
144-
elements = [T]()
145-
}
146-
147-
public mutating func add(item: T) {
148-
if (elements.count < capacity) {
149-
elements.append(item)
150-
}
151-
}
152-
153-
public func sort(algorithm: Sorter) -> [T] {
154-
return algorithm.sort(elements)
155-
}
156-
}
136+
```swift
137+
public struct Bucket<T:Sortable> {
138+
var elements: [T]
139+
let capacity: Int
157140

158-
####Sortable
141+
public init(capacity: Int) {
142+
self.capacity = capacity
143+
elements = [T]()
144+
}
159145

160-
public protocol Sortable: IntConvertible, Comparable {
161-
}
146+
public mutating func add(item: T) {
147+
if (elements.count < capacity) {
148+
elements.append(item)
149+
}
150+
}
162151

163-
####IntConvertible
152+
public func sort(algorithm: Sorter) -> [T] {
153+
return algorithm.sort(elements)
154+
}
155+
}
156+
```
164157

165-
The algorithm is designed to sort integers, so all the elements to be sorted should be mapped to an integer value.
158+
#### Sortable
159+
160+
```swift
161+
public protocol Sortable: IntConvertible, Comparable {
162+
}
163+
```
166164

167-
public protocol IntConvertible {
168-
func toInt() -> Int
169-
}
165+
#### IntConvertible
166+
167+
The algorithm is designed to sort integers, so all the elements to be sorted should be mapped to an integer value.
170168

169+
```swift
170+
public protocol IntConvertible {
171+
func toInt() -> Int
172+
}
173+
```
171174

172-
####Sorter
175+
#### Sorter
173176

174-
public protocol Sorter {
175-
func sort<T:Sortable>(items: [T]) -> [T]
176-
}
177+
```swift
178+
public protocol Sorter {
179+
func sort<T:Sortable>(items: [T]) -> [T]
180+
}
181+
```
177182

178-
####Distributor
183+
#### Distributor
179184

180-
public protocol Distributor {
181-
func distribute<T:Sortable>(element: T, inout buckets: [Bucket<T>])
182-
}
185+
```swift
186+
public protocol Distributor {
187+
func distribute<T:Sortable>(element: T, inout buckets: [Bucket<T>])
188+
}
189+
```
183190

184191
### Custom Sorter and Distributor
185192

186193
The current implementation make use of the following implementations for *Sorter* and *Distributor*.
187194

188195
*Sorter*
189196

190-
public struct InsertionSorter: Sorter {
191-
192-
public init() {}
193-
194-
public func sort<T:Sortable>(items: [T]) -> [T] {
195-
var results = items
196-
for i in 0 ..< results.count {
197-
var j = i
198-
while ( j > 0 && results[j-1] > results[j]) {
199-
200-
let auxiliar = results[j-1]
201-
results[j-1] = results[j]
202-
results[j] = auxiliar
203-
204-
j -= 1
205-
}
206-
}
207-
return results
208-
}
209-
}
197+
```swift
198+
public struct InsertionSorter: Sorter {
199+
public func sort<T:Sortable>(items: [T]) -> [T] {
200+
var results = items
201+
for i in 0 ..< results.count {
202+
var j = i
203+
while ( j > 0 && results[j-1] > results[j]) {
204+
205+
let auxiliar = results[j-1]
206+
results[j-1] = results[j]
207+
results[j] = auxiliar
208+
209+
j -= 1
210+
}
211+
}
212+
return results
213+
}
214+
}
215+
```
210216

211217
*Distributor*
212218

213-
/*
214-
* An example of a simple distribution function that send every elements to
215-
* the bucket representing the range in which it fits.An
216-
*
217-
* If the range of values to sort is 0..<49 i.e, there could be 5 buckets of capacity = 10
218-
* So every element will be classified by the ranges:
219-
*
220-
* - 0 ..< 10
221-
* - 10 ..< 20
222-
* - 20 ..< 30
223-
* - 30 ..< 40
224-
* - 40 ..< 50
225-
*
226-
* By following the formula: element / capacity = #ofBucket
227-
*/
228-
public struct RangeDistributor: Distributor {
229-
230-
public init() {}
231-
232-
public func distribute<T:Sortable>(element: T, inout buckets: [Bucket<T>]) {
233-
let value = element.toInt()
234-
let bucketCapacity = buckets.first!.capacity
235-
236-
let bucketIndex = value / bucketCapacity
237-
buckets[bucketIndex].add(element)
238-
}
239-
}
219+
```swift
220+
/*
221+
* An example of a simple distribution function that send every elements to
222+
* the bucket representing the range in which it fits.
223+
*
224+
* If the range of values to sort is 0..<49 i.e, there could be 5 buckets of capacity = 10
225+
* So every element will be classified by the ranges:
226+
*
227+
* - 0 ..< 10
228+
* - 10 ..< 20
229+
* - 20 ..< 30
230+
* - 30 ..< 40
231+
* - 40 ..< 50
232+
*
233+
* By following the formula: element / capacity = #ofBucket
234+
*/
235+
public struct RangeDistributor: Distributor {
236+
public func distribute<T:Sortable>(element: T, inout buckets: [Bucket<T>]) {
237+
let value = element.toInt()
238+
let bucketCapacity = buckets.first!.capacity
239+
240+
let bucketIndex = value / bucketCapacity
241+
buckets[bucketIndex].add(element)
242+
}
243+
}
244+
```
240245

241246
### Make your own version
242247

243248
By reusing this code and implementing your own *Sorter* and *Distributor* you can experiment with different versions.
244249

245250
## Other variations of Bucket Sort
246251

247-
The following are some of the variation to the General Bucket Sort implemented here:
252+
The following are some of the variation to the general [Bucket Sort](https://en.wikipedia.org/wiki/Bucket_sort) implemented here:
248253

249254
- [Proxmap Sort](https://en.wikipedia.org/wiki/Bucket_sort#ProxmapSort)
250255
- [Histogram Sort](https://en.wikipedia.org/wiki/Bucket_sort#Histogram_sort)
251256
- [Postman Sort](https://en.wikipedia.org/wiki/Bucket_sort#Postman.27s_sort)
252257
- [Shuffle Sort](https://en.wikipedia.org/wiki/Bucket_sort#Shuffle_sort)
253258

259+
*Written for Swift Algorithm Club by Barbara Rodeker. Images from Wikipedia.*

README.markdown

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Fast sorts:
7272

7373
Special-purpose sorts:
7474

75-
- Bucket Sort
75+
- [Bucket Sort](Bucket Sort/) :construction:
7676
- [Counting Sort](Counting Sort/)
7777
- Radix Sort
7878
- [Topological Sort](Topological Sort/)

0 commit comments

Comments
 (0)