Skip to content

Commit 48c7f69

Browse files
committed
Finished README
1 parent 20ed097 commit 48c7f69

File tree

1 file changed

+175
-1
lines changed

1 file changed

+175
-1
lines changed

Ordered Set/README.md

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
An Ordered Set is a collection of unique items in sorted order. Items are usually sorted from least to greatest. The Ordered Set data type is a representation of a [Set in Mathematics](https://en.wikipedia.org/wiki/Set_(mathematics)). It's important to keep in mind that two items can have the same *value* but still may not be equal.
33
For example, we could define "a" and "z" to have the same value (their lengths), but clearly "a" != "z".
44

5-
### Examples of Ordered Sets
5+
## Why use an Ordered Set?
6+
Ordered Sets should be considered for use when you need to require keeping your collection sorted at all times, and do lookups on the collection much more freuqently than inserting or deleting items. A good example would be keeping track of the rankings of players in a scoreboard (see example 2 below). Many of the lookup operations for an Ordered Set are **O(1)**.
7+
8+
### These are Ordered Sets
69
```
710
[1, 2, 3, 6, 8, 10, 1000]
811
Where each item (Integers) has it's normal definition of value and equality
@@ -161,6 +164,177 @@ First, `j` starts at the mid value. Above, we've already checked to see that the
161164
The combined runtime for this function is **O(log(n) + k)** where `n` is the length of the set, and `k` is the number of
162165
items with the same *value* as the one that is being searched for.
163166

167+
Since the set is sorted, the following operations are all **O(1)**:
168+
169+
```swift
170+
// returns the 'maximum' or 'largest' value in the set
171+
public func max() -> T! {
172+
return count == 0 ? nil : internalSet[count - 1]
173+
}
174+
175+
// returns the 'minimum' or 'smallest' value in the set
176+
public func min() -> T! {
177+
return count == 0 ? nil : internalSet[0]
178+
}
179+
180+
// returns the k largest element in the set, if k is in the range [1, count]
181+
// returns nil otherwise
182+
public func kLargest(k: Int) -> T! {
183+
return k > count || k <= 0 ? nil : internalSet[count - k]
184+
}
185+
186+
// returns the k smallest element in the set, if k is in the range [1, count]
187+
// returns nil otherwise
188+
public func kSmallest(k: Int) -> T! {
189+
return k > count || k <= 0 ? nil : internalSet[k - 1]
190+
}
191+
```
192+
193+
## Examples
194+
Below are a few examples that can be found in the playground file.
195+
196+
### Example 1
197+
Here we create a set with random Integers. Pringint the largest/smallest 5 numbers in the set is fairly easy.
198+
``` swift
199+
// Example 1 with type Int
200+
var mySet = OrderedSet<Int>()
201+
202+
// insert random ints into the set
203+
204+
for _ in 0..<50 {
205+
mySet.insert(randomNum(50, max: 500))
206+
}
207+
208+
print(mySet)
209+
210+
print(mySet.max())
211+
print(mySet.min())
212+
213+
// print the 5 largest values
214+
for k in 1..<6 {
215+
print(mySet.kLargest(k))
216+
}
217+
218+
// print the 5 lowest values
219+
for k in 1..<6 {
220+
print(mySet.kSmallest(k))
221+
}
222+
```
223+
224+
### Exmaple 2
225+
In this example we take a look at something a bit more interesting. We define a `Player` struct as follows:
226+
``` swift
227+
struct Player : Comparable {
228+
var name: String! = String.random()
229+
var points = randomNum(0, max: 5000)
230+
231+
init(name: String, points: Int){
232+
self.name = name
233+
self.points = points
234+
}
235+
236+
init(){}
237+
}
238+
239+
// == operator for struct Player
240+
// Player x is equal to Player y if and only if both players have the same name and number of points
241+
func ==(x: Player, y: Player) -> Bool {
242+
return x.name == y.name && x.points == y.points
243+
}
244+
245+
// < operator for struct Player
246+
// Player x is less than Player y if and only if x has less points than y
247+
func <(x: Player, y: Player) -> Bool {
248+
return x.points < y.points
249+
}
250+
```
251+
The set we create will hold players. One thing to note is that two `Player`'s can each have the same value, but are not guaranteed to be equal.
252+
253+
Inserting 20 random players and one player we will track of.
254+
``` swift
255+
// Example 2 with type Player
256+
var playerSet = OrderedSet<Player>()
257+
258+
// populate with random players.
259+
var anotherPlayer = Player()
260+
for _ in 0..<20 {
261+
playerSet.insert(Player())
262+
}
263+
264+
// we'll look for this player later
265+
playerSet.insert(anotherPlayer)
266+
```
267+
268+
Next, we can find the players with the most and least amount of points very quickly.
269+
``` swift
270+
// highest and lowest players:
271+
print(playerSet.max())
272+
print(playerSet.min())
273+
```
274+
275+
Next we use the findIndex function to find out what rank `anotherPlayer` in comparison to the other `Player`s.
276+
``` swift
277+
// we'll find our player now
278+
print("'Another Player (\(anotherPlayer.name))' is ranked at level: \(playerSet.count - playerSet.findIndex(anotherPlayer)) with \(anotherPlayer.points) points")
279+
```
280+
281+
### Example 3
282+
The final example demonstrates the need to look for the right item even after the Binary Search has completed. 9 Players are inserted into the set.
283+
``` swift
284+
285+
var repeatedSet = OrderedSet<Player>()
286+
287+
repeatedSet.insert(Player(name:"Player 1", points: 100))
288+
repeatedSet.insert(Player(name: "Player 1", points: 100))
289+
repeatedSet.insert(Player(name: "Player 2", points: 100))
290+
repeatedSet.insert(Player(name: "Player 3", points: 100))
291+
repeatedSet.insert(Player(name: "Player 4", points: 100))
292+
repeatedSet.insert(Player(name: "Player 5", points: 100))
293+
repeatedSet.insert(Player(name: "Player 6", points: 50))
294+
repeatedSet.insert(Player(name: "Player 7", points: 200))
295+
repeatedSet.insert(Player(name: "Player 8", points: 250))
296+
repeatedSet.insert(Player(name: "Player 9", points: 25))
297+
298+
print(repeatedSet)
299+
```
300+
301+
The set looks something like this:
302+
```
303+
[Player 9, Player 6, Player 1, Player 2, Player 3, Player 4, Player 5, Player 7, Player 8]
304+
```
164305

306+
The next line looks for `Player 2`:
307+
``` swift
308+
print(repeatedSet.findIndex(Player(name: "Player 2", points: 100)))
309+
```
310+
311+
After the Binary Search finishes, the value of `mid` is at index 5
312+
```
313+
[Player 9, Player 6, Player 1, Player 2, Player 3, Player 4, Player 5, Player 7, Player 8]
314+
mid
315+
```
316+
However, we know this may not be where `Player 2` is, so we check both sides of `mid`. The shown Players below are the ones with the same value as `Player 4`, and are the ones we check after the Binary Search.
317+
318+
```
319+
[X, X, Player 1, Player 2, Player 3, Player 4, Player 5, X, X]
320+
mid
321+
```
322+
323+
The code then checks the right of `mid` (Every `Player` with an * below it)
324+
```
325+
[X, X, Player 1, Player 2, Player 3, Player 4, Player 5, X, X]
326+
mid *
327+
```
328+
329+
The right side did not contain the item, so we look at the left side.
330+
```
331+
[X, X, Player 1, Player 2, Player 3, Player 4, Player 5, X, X]
332+
* mid
333+
```
334+
```
335+
[X, X, Player 1, Player 2, Player 3, Player 4, Player 5, X, X]
336+
* mid
337+
```
338+
We've found `Player 2`! Index 3 is then returned.
165339

166340
*Written By Zain Humayun*

0 commit comments

Comments
 (0)