Skip to content

Commit c521136

Browse files
committed
Added more functions
1 parent 53799fd commit c521136

File tree

1 file changed

+86
-6
lines changed

1 file changed

+86
-6
lines changed

Ordered Set/README.md

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@ For example, we could define "a" and "z" to have the same value (their lengths),
44

55
### Examples of Ordered Sets
66
```
7-
{1, 2, 3, 6, 8, 10, 1000}
7+
[1, 2, 3, 6, 8, 10, 1000]
88
Where each item (Integers) has it's normal definition of value and equality
99
```
1010
```
11-
{"a", "is", "set", "this"}
11+
["a", "is", "set", "this"]
1212
Where each item (String) has it's value equal to it's length
1313
```
1414

1515
### These are not Ordered Sets
1616
```
17-
{1, 1, 2, 3, 5, 8}
17+
[1, 1, 2, 3, 5, 8]
1818
This Set violates the property of uniqueness
1919
```
2020
```
21-
{1, 11, 2, 3}
21+
[1, 11, 2, 3]
2222
This Set violates the sorted property
2323
```
2424

@@ -65,10 +65,10 @@ Lets take a look at the insert function first. The insert function first checks
6565
internalSet.append(item)
6666
}
6767
```
68-
The first part of the function checks if the item is already in the set.As we'll see later on, this has an efficiency of **O(log n + k)** where k is the number of items with the same value as the item we are inserting. The second part iterates through the interal array so that it can find a spot for our given item. This is at worse **O(n)**. The insert function for arrays has an efficiency of **O(log(n))**, thus making the insert function for our Ordered Set **O(log(n) + k)**.
68+
The first part of the function checks if the item is already in the set.As we'll see later on, this has an efficiency of **O(log(n) + k)** where k is the number of items with the same value as the item we are inserting. The second part iterates through the interal array so that it can find a spot for our given item. This is at worse **O(n)**. The insert function for arrays has an efficiency of **O(log(n))**, thus making the insert function for our Ordered Set **O(log(n) + k)**.
6969

7070

71-
Next we have the remove function. First check if the item exists. If not, then return and no nothing. If it does exist, remove it.
71+
Next we have the `remove` function. First check if the item exists. If not, then return and no nothing. If it does exist, remove it.
7272

7373
``` swift
7474
// removes an item if it exists
@@ -82,5 +82,85 @@ Next we have the remove function. First check if the item exists. If not, then r
8282
```
8383
Again, because of the `exists` function, the efficiency for remove is **O(log(n) + k)**
8484

85+
The next function is the `findIndex` function which takes in an item of type `T` and returns the index of the item if it is in the set, otherwise returns -1.
86+
87+
``` swift
88+
// returns the index of an item if it exists, otherwise returns -1.
89+
public func findIndex(item: T) -> Int {
90+
var leftBound = 0
91+
var rightBound = count - 1
92+
93+
while leftBound <= rightBound {
94+
let mid = leftBound + ((rightBound - leftBound) / 2)
95+
96+
if internalSet[mid] > item {
97+
rightBound = mid - 1
98+
} else if internalSet[mid] < item {
99+
leftBound = mid + 1
100+
} else {
101+
// check the mid value to see if it is the item we are looking for
102+
if internalSet[mid] == item {
103+
return mid
104+
}
105+
106+
var j = mid
107+
108+
// check right side of mid
109+
while j < internalSet.count - 1 && !(internalSet[j] < internalSet[j + 1]) {
110+
if internalSet[j + 1] == item {
111+
return j + 1
112+
}
113+
114+
j += 1
115+
}
116+
117+
j = mid
118+
119+
// check right side of mid
120+
while j > 0 && !(internalSet[j] < internalSet[j - 1]) {
121+
if internalSet[j - 1] == item {
122+
return j - 1
123+
}
124+
125+
j -= 1
126+
}
127+
return -1
128+
}
129+
}
130+
131+
return -1
132+
}
133+
```
134+
Since our set is sorted, we can use a binary search to quickly search for the item. If you are not familiar with the concept of binary search, we have an article all about it [here](../Binary\ Search).
135+
136+
Since a set can contain multiple items with the same *value*, it is important to check to see if we have the correct item.
137+
138+
For example, consider this Ordered Set
139+
```
140+
["a", "b", "c", "longer string", "even longer string"]
141+
Where the value of each String is equal to it's length.
142+
```
143+
The call `findIndex("a")` with the traditional implementation of Binary Search would give us the value of 2, however we know that "a" is located at index 0. Thus, we need to check the items with the same *value* to the right and left of the mid value.
144+
145+
The code to check the left and right side are similar so we will only look at the code that checks the left side.
146+
``` swift
147+
j = mid
148+
149+
// check right side of mid
150+
while j > 0 && !(internalSet[j] < internalSet[j - 1]) {
151+
if internalSet[j - 1] == item {
152+
return j - 1
153+
}
154+
155+
j -= 1
156+
}
157+
return -1
158+
```
159+
First, `j` starts at the mid value. Above, we've already checked to see that the item at index `j` is not equal to the item we are looking for. Then, we keep looping until we either reach the end of the array, or hit an element which has a lower value than the current item at index `j`. If the item at value `j - 1` is equal to the one we are looking for, we return that index, otherwise we keep decreasing `j`. Once the loop terminates, we were unable to find the item and so we return -1.
160+
161+
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
162+
items with the same *value* as the one that is being searched for.
163+
164+
85165

86166
*Written By Zain Humayun*

0 commit comments

Comments
 (0)