diff --git a/Algorithm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Algorithm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Algorithm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Package.swift b/Package.swift
index 090a41f..d1d7762 100644
--- a/Package.swift
+++ b/Package.swift
@@ -9,7 +9,8 @@ let package = Package(
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "Algorithm",
- targets: ["Algorithm"]),
+ targets: ["Algorithm"]
+ )
],
dependencies: [
// Dependencies declare other packages that this package depends on.
@@ -21,10 +22,12 @@ let package = Package(
.target(
name: "Algorithm",
dependencies: [],
- path: "Sources"),
+ path: "Sources"
+ ),
.testTarget(
name: "AlgorithmTests",
dependencies: ["Algorithm"],
- path: "Tests"),
+ path: "Tests"
+ )
]
)
diff --git a/Sources/Algorithm+Array.swift b/Sources/Algorithm+Array.swift
index 5f69e3c..fba1d3e 100644
--- a/Sources/Algorithm+Array.swift
+++ b/Sources/Algorithm+Array.swift
@@ -24,117 +24,116 @@
*/
extension Array where Element: Equatable {
- /**
- Removes a given Element from an Array if it exists.
- - Parameter object: An Element.
- - Returns: An optional Element if the removed
- element exists.
- */
- @discardableResult
- mutating func remove(object: Element) -> Element? {
- return firstIndex(of: object).map { self.remove(at: $0) }
- }
-
- /**
- Removes a list of given Elements from an Array if
- they exists.
- - Parameter objects: A list of Elements.
- */
- mutating func remove(objects: Element...) {
- remove(objects: objects)
- }
-
- /**
- Removes an Array of given Elements from an Array if
- they exists.
- - Parameter objects: An Array of Elements.
- */
- mutating func remove(objects: [Element]) {
- objects.forEach {
- self.remove(object: $0)
+ /**
+ Removes a given Element from an Array if it exists.
+ - Parameter object: An Element.
+ - Returns: An optional Element if the removed
+ element exists.
+ */
+ @discardableResult
+ mutating func remove(object: Element) -> Element? {
+ return firstIndex(of: object).map { self.remove(at: $0) }
}
- }
-
- /**
- The total count for the given Elements.
- - Parameter of elements: A list of Elements.
- - Returns: An Int.
- */
- public func count(of elements: Element...) -> Int {
- return count(of: elements)
- }
-
- /**
- The total count for the given Elements.
- - Parameter of elements: An Array of Elements.
- - Returns: An Int.
- */
- public func count(of elements: [Element]) -> Int {
-
- var c = 0
- for e in elements {
- for x in self where e == x {
- c += 1
- }
+
+ /**
+ Removes a list of given Elements from an Array if
+ they exists.
+ - Parameter objects: A list of Elements.
+ */
+ mutating func remove(objects: Element...) {
+ remove(objects: objects)
}
- return c
- }
-
- /**
- The probability of getting the given Elements.
- - Parameter of elements: A list of Elements.
- - Returns: A Double.
- */
- public func probability(of elements: Element...) -> Double {
- return probability(of: elements)
- }
-
- /**
- The probability of getting the given Elements.
- - Parameter of elements: An Array of Elements.
- - Returns: A Double.
- */
- public func probability(of elements: [Element]) -> Double {
- return 0 < count ? Double(count(of: elements)) / Double(count) : 0
- }
-
- /**
- A probability method that uses a block to determine the member state of a condition.
- - Parameter of elements: A list of Elements.
- - Returns: A Double.
- */
- public func probability(execute block: @escaping (Element) -> Bool) -> Double {
- guard 0 < count else {
- return 0
+
+ /**
+ Removes an Array of given Elements from an Array if
+ they exists.
+ - Parameter objects: An Array of Elements.
+ */
+ mutating func remove(objects: [Element]) {
+ objects.forEach {
+ self.remove(object: $0)
+ }
}
-
- var c = 0
- for e in self {
- if block(e) {
- c += 1
- }
+
+ /**
+ The total count for the given Elements.
+ - Parameter of elements: A list of Elements.
+ - Returns: An Int.
+ */
+ public func count(of elements: Element...) -> Int {
+ return count(of: elements)
+ }
+
+ /**
+ The total count for the given Elements.
+ - Parameter of elements: An Array of Elements.
+ - Returns: An Int.
+ */
+ public func count(of elements: [Element]) -> Int {
+ var c = 0
+ for e in elements {
+ for x in self where e == x {
+ c += 1
+ }
+ }
+ return c
+ }
+
+ /**
+ The probability of getting the given Elements.
+ - Parameter of elements: A list of Elements.
+ - Returns: A Double.
+ */
+ public func probability(of elements: Element...) -> Double {
+ return probability(of: elements)
+ }
+
+ /**
+ The probability of getting the given Elements.
+ - Parameter of elements: An Array of Elements.
+ - Returns: A Double.
+ */
+ public func probability(of elements: [Element]) -> Double {
+ return count > 0 ? Double(count(of: elements)) / Double(count) : 0
+ }
+
+ /**
+ A probability method that uses a block to determine the member state of a condition.
+ - Parameter of elements: A list of Elements.
+ - Returns: A Double.
+ */
+ public func probability(execute block: @escaping (Element) -> Bool) -> Double {
+ guard count > 0 else {
+ return 0
+ }
+
+ var c = 0
+ for e in self {
+ if block(e) {
+ c += 1
+ }
+ }
+
+ return Double(c) / Double(count)
+ }
+
+ /**
+ Calculates the expected value of elements based on a given number of trials.
+ - Parameter trials: Number of trials.
+ - Parameter elements: A list of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for elements: Element...) -> Double {
+ return expectedValue(trials: trials, for: elements)
+ }
+
+ /**
+ Calculates the expected value of elements based on a given number of trials.
+ - Parameter trials: Number of trials.
+ - Parameter elements: An Array of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for elements: [Element]) -> Double {
+ return Double(trials) * probability(of: elements)
}
-
- return Double(c) / Double(count)
- }
-
- /**
- Calculates the expected value of elements based on a given number of trials.
- - Parameter trials: Number of trials.
- - Parameter elements: A list of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for elements: Element...) -> Double {
- return expectedValue(trials: trials, for: elements)
- }
-
- /**
- Calculates the expected value of elements based on a given number of trials.
- - Parameter trials: Number of trials.
- - Parameter elements: An Array of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for elements: [Element]) -> Double {
- return Double(trials) * probability(of: elements)
- }
}
diff --git a/Sources/Algorithm+Set.swift b/Sources/Algorithm+Set.swift
index dac8904..b1f6c1d 100644
--- a/Sources/Algorithm+Set.swift
+++ b/Sources/Algorithm+Set.swift
@@ -24,87 +24,87 @@
*/
extension Set: Probable {
- /**
- The total count for the given Elements.
- - Parameter of elements: A list of Elements.
- - Returns: An Int.
- */
- public func count(of elements: Element...) -> Int {
- return count(of: elements)
- }
-
- /**
- The total count for the given Elements.
- - Parameter of elements: An Array of Elements.
- - Returns: An Int.
- */
- public func count(of elements: [Element]) -> Int {
- var c = 0
- for e in elements {
- for x in self {
- if e == x {
- c += 1
+ /**
+ The total count for the given Elements.
+ - Parameter of elements: A list of Elements.
+ - Returns: An Int.
+ */
+ public func count(of elements: Element...) -> Int {
+ return count(of: elements)
+ }
+
+ /**
+ The total count for the given Elements.
+ - Parameter of elements: An Array of Elements.
+ - Returns: An Int.
+ */
+ public func count(of elements: [Element]) -> Int {
+ var c = 0
+ for e in elements {
+ for x in self {
+ if e == x {
+ c += 1
+ }
+ }
+ }
+ return c
+ }
+
+ /**
+ The probability of getting the given Elements.
+ - Parameter of elements: A list of Elements.
+ - Returns: A Double.
+ */
+ public func probability(of elements: Element...) -> Double {
+ return probability(of: elements)
+ }
+
+ /**
+ The probability of getting the given Elements.
+ - Parameter of elements: An Array of Elements.
+ - Returns: A Double.
+ */
+ public func probability(of elements: [Element]) -> Double {
+ return count > 0 ? Double(count(of: elements)) / Double(count) : 0
+ }
+
+ /**
+ A probability method that uses a block to determine the member state of a condition.
+ - Parameter of elements: A list of Elements.
+ - Returns: A Double.
+ */
+ public func probability(of block: @escaping (Element) -> Bool) -> Double {
+ guard count > 0 else {
+ return 0
+ }
+
+ var c = 0
+ for e in self {
+ if block(e) {
+ c += 1
+ }
}
- }
+
+ return Double(c) / Double(count)
}
- return c
- }
-
- /**
- The probability of getting the given Elements.
- - Parameter of elements: A list of Elements.
- - Returns: A Double.
- */
- public func probability(of elements: Element...) -> Double {
- return probability(of: elements)
- }
-
- /**
- The probability of getting the given Elements.
- - Parameter of elements: An Array of Elements.
- - Returns: A Double.
- */
- public func probability(of elements: [Element]) -> Double {
- return 0 < count ? Double(count(of: elements)) / Double(count) : 0
- }
-
- /**
- A probability method that uses a block to determine the member state of a condition.
- - Parameter of elements: A list of Elements.
- - Returns: A Double.
- */
- public func probability(of block: @escaping (Element) -> Bool) -> Double {
- guard 0 < count else {
- return 0
+
+ /**
+ Calculates the expected value of elements based on a given number of trials.
+ - Parameter trials: Number of trials.
+ - Parameter elements: A list of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for elements: Element...) -> Double {
+ return expectedValue(trials: trials, for: elements)
}
-
- var c = 0
- for e in self {
- if block(e) {
- c += 1
- }
+
+ /**
+ Calculates the expected value of elements based on a given number of trials.
+ - Parameter trials: Number of trials.
+ - Parameter elements: An Array of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for elements: [Element]) -> Double {
+ return Double(trials) * probability(of: elements)
}
-
- return Double(c) / Double(count)
- }
-
- /**
- Calculates the expected value of elements based on a given number of trials.
- - Parameter trials: Number of trials.
- - Parameter elements: A list of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for elements: Element...) -> Double {
- return expectedValue(trials: trials, for: elements)
- }
-
- /**
- Calculates the expected value of elements based on a given number of trials.
- - Parameter trials: Number of trials.
- - Parameter elements: An Array of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for elements: [Element]) -> Double {
- return Double(trials) * probability(of: elements)
- }
}
diff --git a/Sources/Deque.swift b/Sources/Deque.swift
index 44ee648..640c46b 100644
--- a/Sources/Deque.swift
+++ b/Sources/Deque.swift
@@ -24,137 +24,137 @@
*/
public struct Deque: CustomStringConvertible, Sequence {
- public typealias Iterator = AnyIterator
-
- /**
- :name: list
- :description: Underlying element structure.
- - returns: DoublyLinkedList
- */
- private var list: DoublyLinkedList
-
- /**
- :name: count
- :description: Total number of items in the Deque.
- - returns: Int
- */
- public var count: Int {
- return list.count
- }
-
- /**
- :name: front
- :description: Get the element at the front of the Deque
- and do not remove it.
- - returns: Element?
- */
- public var front: Element? {
- return list.front
- }
-
- /**
- :name: back
- :description: Get the element at the back of the Deque
- and do not remove it.
- - returns: Element?
- */
- public var back: Element? {
- return list.back
- }
-
- /**
- :name: isEmpty
- :description: A boolean of whether the Deque is empty.
- - returns: Bool
- */
- public var isEmpty: Bool {
- return list.isEmpty
- }
-
- /**
- :name: description
- :description: Conforms to the Printable Protocol.
- - returns: String
- */
- public var description: String {
- return list.description
- }
-
- /**
- :name: init
- :description: Constructor.
- */
- public init() {
- list = DoublyLinkedList()
- }
-
- /**
- Conforms to the SequenceType Protocol. Returns the next value
- in the sequence of nodes.
- - Returns: A Deque.Iterator.
- */
- public func makeIterator() -> Deque.Iterator {
- return list.makeIterator()
- }
-
- /**
- :name: insertAtFront
- :description: Insert a new element at the front of the Deque.
- */
- mutating public func insert(atFront element: Element) {
- list.insert(atFront: element)
- }
-
- /**
- :name: removeAtFront
- :description: Get the element at the front of the Deque
- and remove it.
- - returns: Element?
- */
- mutating public func removeAtFront() -> Element? {
- return list.removeAtFront()
- }
-
- /**
- :name: insertAtBack
- :description: Insert a new element at the back of the Deque.
- */
- mutating public func insert(atBack element: Element) {
- list.insert(atBack: element)
- }
-
- /**
- :name: removeAtBack
- :description: Get the element at the back of the Deque
- and remove it.
- - returns: Element?
- */
- mutating public func removeAtBack() -> Element? {
- return list.removeAtBack()
- }
-
- /**
- :name: removeAll
- :description: Remove all elements from the Deque.
- */
- mutating public func removeAll() {
- list.removeAll()
- }
+ public typealias Iterator = AnyIterator
+
+ /**
+ :name: list
+ :description: Underlying element structure.
+ - returns: DoublyLinkedList
+ */
+ private var list: DoublyLinkedList
+
+ /**
+ :name: count
+ :description: Total number of items in the Deque.
+ - returns: Int
+ */
+ public var count: Int {
+ return list.count
+ }
+
+ /**
+ :name: front
+ :description: Get the element at the front of the Deque
+ and do not remove it.
+ - returns: Element?
+ */
+ public var front: Element? {
+ return list.front
+ }
+
+ /**
+ :name: back
+ :description: Get the element at the back of the Deque
+ and do not remove it.
+ - returns: Element?
+ */
+ public var back: Element? {
+ return list.back
+ }
+
+ /**
+ :name: isEmpty
+ :description: A boolean of whether the Deque is empty.
+ - returns: Bool
+ */
+ public var isEmpty: Bool {
+ return list.isEmpty
+ }
+
+ /**
+ :name: description
+ :description: Conforms to the Printable Protocol.
+ - returns: String
+ */
+ public var description: String {
+ return list.description
+ }
+
+ /**
+ :name: init
+ :description: Constructor.
+ */
+ public init() {
+ list = DoublyLinkedList()
+ }
+
+ /**
+ Conforms to the SequenceType Protocol. Returns the next value
+ in the sequence of nodes.
+ - Returns: A Deque.Iterator.
+ */
+ public func makeIterator() -> Deque.Iterator {
+ return list.makeIterator()
+ }
+
+ /**
+ :name: insertAtFront
+ :description: Insert a new element at the front of the Deque.
+ */
+ public mutating func insert(atFront element: Element) {
+ list.insert(atFront: element)
+ }
+
+ /**
+ :name: removeAtFront
+ :description: Get the element at the front of the Deque
+ and remove it.
+ - returns: Element?
+ */
+ public mutating func removeAtFront() -> Element? {
+ return list.removeAtFront()
+ }
+
+ /**
+ :name: insertAtBack
+ :description: Insert a new element at the back of the Deque.
+ */
+ public mutating func insert(atBack element: Element) {
+ list.insert(atBack: element)
+ }
+
+ /**
+ :name: removeAtBack
+ :description: Get the element at the back of the Deque
+ and remove it.
+ - returns: Element?
+ */
+ public mutating func removeAtBack() -> Element? {
+ return list.removeAtBack()
+ }
+
+ /**
+ :name: removeAll
+ :description: Remove all elements from the Deque.
+ */
+ public mutating func removeAll() {
+ list.removeAll()
+ }
}
-public func +(lhs: Deque, rhs: Deque) -> Deque {
- var d = Deque()
- for x in lhs {
- d.insert(atBack: x)
- }
- for x in rhs {
- d.insert(atBack: x)
- }
- return d
+public func + (lhs: Deque, rhs: Deque) -> Deque {
+ var d = Deque()
+ for x in lhs {
+ d.insert(atBack: x)
+ }
+ for x in rhs {
+ d.insert(atBack: x)
+ }
+ return d
}
-public func +=(lhs: inout Deque, rhs: Deque) {
- for x in rhs {
- lhs.insert(atBack: x)
- }
+public func += (lhs: inout Deque, rhs: Deque) {
+ for x in rhs {
+ lhs.insert(atBack: x)
+ }
}
diff --git a/Sources/DoublyLinkedList.swift b/Sources/DoublyLinkedList.swift
index 6455c04..e63ad42 100644
--- a/Sources/DoublyLinkedList.swift
+++ b/Sources/DoublyLinkedList.swift
@@ -24,330 +24,330 @@
*/
public struct DoublyLinkedList: CustomStringConvertible, Sequence {
- public typealias Iterator = AnyIterator
-
- /**
- First node in the list.
- - Returns: An optional DoublyLinkedListNode.
- */
- private var head: DoublyLinkedListNode?
-
- /**
- Last node in list.
- - Returns: An optional DoublyLinkedListNode.
- */
- private var tail: DoublyLinkedListNode?
-
- /**
- Current cursor position when iterating.
- - Returns: An optional DoublyLinkedListNode.
- */
- private var current: DoublyLinkedListNode?
-
- /**
- Number of nodes in DoublyLinkedList.
- - Returns: An Int.
- */
- public private(set) var count: Int
-
- /**
- Conforms to Printable Protocol.
- - Returns: A String.
- */
- public var description: String {
- var output = "("
- var c = 0
- var x = head
- while nil !== x {
- output += "\(String(describing: x))"
- c += 1
- if c != count {
- output += ", "
- }
- x = x!.next
+ public typealias Iterator = AnyIterator
+
+ /**
+ First node in the list.
+ - Returns: An optional DoublyLinkedListNode.
+ */
+ private var head: DoublyLinkedListNode?
+
+ /**
+ Last node in list.
+ - Returns: An optional DoublyLinkedListNode.
+ */
+ private var tail: DoublyLinkedListNode?
+
+ /**
+ Current cursor position when iterating.
+ - Returns: An optional DoublyLinkedListNode.
+ */
+ private var current: DoublyLinkedListNode?
+
+ /**
+ Number of nodes in DoublyLinkedList.
+ - Returns: An Int.
+ */
+ public private(set) var count: Int
+
+ /**
+ Conforms to Printable Protocol.
+ - Returns: A String.
+ */
+ public var description: String {
+ var output = "("
+ var c = 0
+ var x = head
+ while nil !== x {
+ output += "\(String(describing: x))"
+ c += 1
+ if c != count {
+ output += ", "
+ }
+ x = x!.next
+ }
+ output += ")"
+ return output
}
- output += ")"
- return output
- }
-
- /**
- Retrieves the data at first node of the DoublyLinkedList.
- - Returns: An optional Element.
- */
- public var front: Element? {
- return head?.element
- }
-
- /**
- Retrieves the element at the back node of teh DoublyLinkedList.
- - Returns: An optional Element.
- */
- public var back: Element? {
- return tail?.element
- }
-
- /**
- Retrieves the element at the current iterator position
- in the DoublyLinkedList.
- - Returns: An optional Element.
- */
- public var cursor: Element? {
- return current?.element
- }
-
- /**
- A boolean of whether the DoublyLinkedList is empty.
- - Returns: A boolean indicating if the DoubleLinkedList is
- empty or not, true if yes, false otherwise.
- */
- public var isEmpty: Bool {
- return 0 == count
- }
-
- /**
- A boolean of whether the cursor has reached the back of the
- DoublyLinkedList.
- - Returns: A boolean indicating if the cursor is pointing at
- the back Element, true if yes, false otherwise.
- */
- public var isCursorAtBack: Bool {
- return nil == cursor
- }
-
- /**
- A boolean of whether the cursor has reached the front of the
- DoublyLinkedList.
- - Returns: A boolean indicating if the cursor is pointing at
- the front Element, true if yes, false otherwise.
- */
- public var isCursorAtFront: Bool {
- return nil == cursor
- }
-
- /// An initializer.
- public init() {
- count = 0
- reset()
- }
-
- /**
- Retrieves the element at the poistion after the
- current cursor poistion. Also moves the cursor
- to that node.
- - Returns: An optional Element.
- */
- @discardableResult
- mutating public func next() -> Element? {
- current = current?.next
- return current?.element
- }
-
- /**
- Retrieves the element at the poistion before the
- current cursor poistion. Also moves the cursor
- to that node.
- - Returns: An optional Element.
- */
- @discardableResult
- mutating public func previous() -> Element? {
- current = current?.previous
- return current?.element
- }
-
- /**
- Conforms to the SequenceType Protocol. Returns the next value
- in the sequence of nodes.
- - Returns: A DoublyLinkedList.Iterator.
- */
- public func makeIterator() -> DoublyLinkedList.Iterator {
- var it = head
- return AnyIterator {
- defer {
- it = it?.next
- }
- return it?.element
+
+ /**
+ Retrieves the data at first node of the DoublyLinkedList.
+ - Returns: An optional Element.
+ */
+ public var front: Element? {
+ return head?.element
}
- }
-
- /// Removes all nodes from the DoublyLinkedList.
- mutating public func removeAll() {
- while !isEmpty {
- _ = removeAtFront()
+
+ /**
+ Retrieves the element at the back node of teh DoublyLinkedList.
+ - Returns: An optional Element.
+ */
+ public var back: Element? {
+ return tail?.element
}
- }
-
- /**
- Inserts a new Element at the front of the DoublyLinkedList.
- - Parameter atFront: An Element.
- */
- mutating public func insert(atFront element: Element) {
- var z: DoublyLinkedListNode
- if 0 == count {
- z = DoublyLinkedListNode(next: nil, previous: nil, element: element)
- tail = z
- } else {
- z = DoublyLinkedListNode(next: head, previous: nil, element: element)
- head!.previous = z
+
+ /**
+ Retrieves the element at the current iterator position
+ in the DoublyLinkedList.
+ - Returns: An optional Element.
+ */
+ public var cursor: Element? {
+ return current?.element
}
- head = z
- count += 1
- if 1 == count {
- current = head
- } else if head === current {
- current = head!.next
+
+ /**
+ A boolean of whether the DoublyLinkedList is empty.
+ - Returns: A boolean indicating if the DoubleLinkedList is
+ empty or not, true if yes, false otherwise.
+ */
+ public var isEmpty: Bool {
+ return count == 0
}
- }
-
- /**
- Removes the element at the front position.
- - Returns: An optional Element.
- */
- @discardableResult
- mutating public func removeAtFront() -> Element? {
- if 0 == count {
- return nil
+
+ /**
+ A boolean of whether the cursor has reached the back of the
+ DoublyLinkedList.
+ - Returns: A boolean indicating if the cursor is pointing at
+ the back Element, true if yes, false otherwise.
+ */
+ public var isCursorAtBack: Bool {
+ return cursor == nil
}
- let element: Element? = head!.element
- count -= 1
- if 0 == count {
- reset()
- } else {
- head = head!.next
+
+ /**
+ A boolean of whether the cursor has reached the front of the
+ DoublyLinkedList.
+ - Returns: A boolean indicating if the cursor is pointing at
+ the front Element, true if yes, false otherwise.
+ */
+ public var isCursorAtFront: Bool {
+ return cursor == nil
}
- return element
- }
-
- /**
- Inserts a new Element at the back of the DoublyLinkedList.
- - Parameter atBack: An Element.
- */
- mutating public func insert(atBack element: Element) {
- var z: DoublyLinkedListNode
- if 0 == count {
- z = DoublyLinkedListNode(next: nil, previous: nil, element: element)
- head = z
- } else {
- z = DoublyLinkedListNode(next: nil, previous: tail, element: element)
- tail!.next = z
+
+ /// An initializer.
+ public init() {
+ count = 0
+ reset()
}
- tail = z
- count += 1
- if 1 == count {
- current = tail
- } else if tail === current {
- current = tail!.previous
+
+ /**
+ Retrieves the element at the poistion after the
+ current cursor poistion. Also moves the cursor
+ to that node.
+ - Returns: An optional Element.
+ */
+ @discardableResult
+ public mutating func next() -> Element? {
+ current = current?.next
+ return current?.element
}
- }
-
- /**
- Removes the element at the back position.
- - Returns: An optional Element.
- */
- @discardableResult
- mutating public func removeAtBack() -> Element? {
- if 0 == count {
- return nil
+
+ /**
+ Retrieves the element at the poistion before the
+ current cursor poistion. Also moves the cursor
+ to that node.
+ - Returns: An optional Element.
+ */
+ @discardableResult
+ public mutating func previous() -> Element? {
+ current = current?.previous
+ return current?.element
}
- let element = tail?.element
- count -= 1
- if 0 == count {
- reset()
- } else {
- tail = tail?.previous
+
+ /**
+ Conforms to the SequenceType Protocol. Returns the next value
+ in the sequence of nodes.
+ - Returns: A DoublyLinkedList.Iterator.
+ */
+ public func makeIterator() -> DoublyLinkedList.Iterator {
+ var it = head
+ return AnyIterator {
+ defer {
+ it = it?.next
+ }
+ return it?.element
+ }
}
- return element
- }
-
- /// Move the cursor to the front of the DoublyLinkedList.
- mutating public func cursorToFront() {
- current = head
- }
-
- /// Move the cursor to the back of the DoublyLinkedList.
- mutating public func cursorToBack() {
- current = tail
- }
-
- /**
- Inserts a new Element before the cursor position.
- - Parameter beforeCursor element: An Element.
- */
- mutating public func insert(beforeCursor element: Element) {
- if nil == current || head === current {
- insert(atFront: element)
- } else {
- let z = DoublyLinkedListNode(next: current, previous: current!.previous, element: element)
- current!.previous?.next = z
- current!.previous = z
- count += 1
+
+ /// Removes all nodes from the DoublyLinkedList.
+ public mutating func removeAll() {
+ while !isEmpty {
+ _ = removeAtFront()
+ }
}
- }
-
- /**
- Inserts a new Element after the cursor position.
- - Parameter afterCursor element: An Element.
- */
- mutating public func insert(afterCursor element: Element) {
- if nil == current || tail === current {
- insert(atBack: element)
- } else {
- let z = DoublyLinkedListNode(next: current!.next, previous: current, element: element)
- current!.next?.previous = z
- current!.next = z
- count += 1
+
+ /**
+ Inserts a new Element at the front of the DoublyLinkedList.
+ - Parameter atFront: An Element.
+ */
+ public mutating func insert(atFront element: Element) {
+ var z: DoublyLinkedListNode
+ if count == 0 {
+ z = DoublyLinkedListNode(next: nil, previous: nil, element: element)
+ tail = z
+ } else {
+ z = DoublyLinkedListNode(next: head, previous: nil, element: element)
+ head!.previous = z
+ }
+ head = z
+ count += 1
+ if count == 1 {
+ current = head
+ } else if head === current {
+ current = head!.next
+ }
}
- }
-
- /**
- Removes the element at the cursor position.
- - Returns: An optional Element.
- */
- @discardableResult
- mutating public func removeAtCursor() -> Element? {
- if 1 >= count {
- return removeAtFront()
- } else {
- let element = current?.element
- current?.previous?.next = current?.next
- current?.next?.previous = current?.previous
- if tail === current {
- current = tail?.previous
- tail = current
- } else if head === current {
- current = head?.next
- head = current
- } else {
- current = current?.next
- }
- count -= 1
- return element
+
+ /**
+ Removes the element at the front position.
+ - Returns: An optional Element.
+ */
+ @discardableResult
+ public mutating func removeAtFront() -> Element? {
+ if count == 0 {
+ return nil
+ }
+ let element: Element? = head!.element
+ count -= 1
+ if count == 0 {
+ reset()
+ } else {
+ head = head!.next
+ }
+ return element
+ }
+
+ /**
+ Inserts a new Element at the back of the DoublyLinkedList.
+ - Parameter atBack: An Element.
+ */
+ public mutating func insert(atBack element: Element) {
+ var z: DoublyLinkedListNode
+ if count == 0 {
+ z = DoublyLinkedListNode(next: nil, previous: nil, element: element)
+ head = z
+ } else {
+ z = DoublyLinkedListNode(next: nil, previous: tail, element: element)
+ tail!.next = z
+ }
+ tail = z
+ count += 1
+ if count == 1 {
+ current = tail
+ } else if tail === current {
+ current = tail!.previous
+ }
+ }
+
+ /**
+ Removes the element at the back position.
+ - Returns: An optional Element.
+ */
+ @discardableResult
+ public mutating func removeAtBack() -> Element? {
+ if count == 0 {
+ return nil
+ }
+ let element = tail?.element
+ count -= 1
+ if count == 0 {
+ reset()
+ } else {
+ tail = tail?.previous
+ }
+ return element
+ }
+
+ /// Move the cursor to the front of the DoublyLinkedList.
+ public mutating func cursorToFront() {
+ current = head
+ }
+
+ /// Move the cursor to the back of the DoublyLinkedList.
+ public mutating func cursorToBack() {
+ current = tail
+ }
+
+ /**
+ Inserts a new Element before the cursor position.
+ - Parameter beforeCursor element: An Element.
+ */
+ public mutating func insert(beforeCursor element: Element) {
+ if current == nil || head === current {
+ insert(atFront: element)
+ } else {
+ let z = DoublyLinkedListNode(next: current, previous: current!.previous, element: element)
+ current!.previous?.next = z
+ current!.previous = z
+ count += 1
+ }
+ }
+
+ /**
+ Inserts a new Element after the cursor position.
+ - Parameter afterCursor element: An Element.
+ */
+ public mutating func insert(afterCursor element: Element) {
+ if current == nil || tail === current {
+ insert(atBack: element)
+ } else {
+ let z = DoublyLinkedListNode(next: current!.next, previous: current, element: element)
+ current!.next?.previous = z
+ current!.next = z
+ count += 1
+ }
+ }
+
+ /**
+ Removes the element at the cursor position.
+ - Returns: An optional Element.
+ */
+ @discardableResult
+ public mutating func removeAtCursor() -> Element? {
+ if count <= 1 {
+ return removeAtFront()
+ } else {
+ let element = current?.element
+ current?.previous?.next = current?.next
+ current?.next?.previous = current?.previous
+ if tail === current {
+ current = tail?.previous
+ tail = current
+ } else if head === current {
+ current = head?.next
+ head = current
+ } else {
+ current = current?.next
+ }
+ count -= 1
+ return element
+ }
+ }
+
+ /**
+ Removes all elements and resets the head, tail, and cursor
+ to the sentinel value.
+ */
+ private mutating func reset() {
+ head = nil
+ tail = nil
+ current = nil
}
- }
-
- /**
- Removes all elements and resets the head, tail, and cursor
- to the sentinel value.
- */
- mutating private func reset() {
- head = nil
- tail = nil
- current = nil
- }
}
-public func +(lhs: DoublyLinkedList, rhs: DoublyLinkedList) -> DoublyLinkedList {
- var l = DoublyLinkedList()
- for x in lhs {
- l.insert(atBack: x)
- }
- for x in rhs {
- l.insert(atBack: x)
- }
- return l
+public func + (lhs: DoublyLinkedList, rhs: DoublyLinkedList) -> DoublyLinkedList {
+ var l = DoublyLinkedList()
+ for x in lhs {
+ l.insert(atBack: x)
+ }
+ for x in rhs {
+ l.insert(atBack: x)
+ }
+ return l
}
-public func +=(lhs: inout DoublyLinkedList, rhs: DoublyLinkedList) {
- for x in rhs {
- lhs.insert(atBack: x)
- }
+public func += (lhs: inout DoublyLinkedList, rhs: DoublyLinkedList) {
+ for x in rhs {
+ lhs.insert(atBack: x)
+ }
}
diff --git a/Sources/DoublyLinkedListNode.swift b/Sources/DoublyLinkedListNode.swift
index 130f9bb..d7f5303 100644
--- a/Sources/DoublyLinkedListNode.swift
+++ b/Sources/DoublyLinkedListNode.swift
@@ -24,43 +24,43 @@
*/
internal class DoublyLinkedListNode: CustomStringConvertible {
- /**
- :name: next
- :description: Points to the successor element in the DoublyLinkedList.
- - returns: DoublyLinkedListNode?
- */
- internal var next: DoublyLinkedListNode?
-
- /**
- :name: previous
- :description: points to the predacessor element in the DoublyLinkedList.
- - returns: DoublyLinkedListNode?
- */
- internal var previous: DoublyLinkedListNode?
-
- /**
- :name: data
- :description: Satellite data.
- - returns: Element?
- */
- internal var element: Element?
-
- /**
- :name: description
- :description: Conforms to the Printable Protocol.
- - returns: String
- */
- internal var description: String {
- return "\(String(describing: element))"
- }
-
- /**
- :name: init
- :description: Constructor.
- */
- internal init(next: DoublyLinkedListNode?, previous: DoublyLinkedListNode?, element: Element?) {
- self.next = next
- self.previous = previous
- self.element = element
- }
+ /**
+ :name: next
+ :description: Points to the successor element in the DoublyLinkedList.
+ - returns: DoublyLinkedListNode?
+ */
+ internal var next: DoublyLinkedListNode?
+
+ /**
+ :name: previous
+ :description: points to the predacessor element in the DoublyLinkedList.
+ - returns: DoublyLinkedListNode?
+ */
+ internal var previous: DoublyLinkedListNode?
+
+ /**
+ :name: data
+ :description: Satellite data.
+ - returns: Element?
+ */
+ internal var element: Element?
+
+ /**
+ :name: description
+ :description: Conforms to the Printable Protocol.
+ - returns: String
+ */
+ internal var description: String {
+ return "\(String(describing: element))"
+ }
+
+ /**
+ :name: init
+ :description: Constructor.
+ */
+ internal init(next: DoublyLinkedListNode?, previous: DoublyLinkedListNode?, element: Element?) {
+ self.next = next
+ self.previous = previous
+ self.element = element
+ }
}
diff --git a/Sources/Probable.swift b/Sources/Probable.swift
index 2617ba3..a7e1f5d 100644
--- a/Sources/Probable.swift
+++ b/Sources/Probable.swift
@@ -24,49 +24,49 @@
*/
internal protocol Probable {
- associatedtype ProbableElement: Equatable
-
- /**
- The instance count of elements.
- - Parameter of elements: A list of ProbableElements
- - Returns: An Int.
- */
- func count(of elements: ProbableElement...) -> Int
-
- /**
- The instance count of elements.
- - Parameter of elements: An Array of ProbableElements.
- - Returns: An Int.
- */
- func count(of elements: [ProbableElement]) -> Int
-
- /**
- The probability of given elements.
- - Parameter of elements: A list of ProbableElements.
- - Returns: A Double.
- */
- func probability(of elements: ProbableElement...) -> Double
-
- /**
- The probability of given elements.
- - Parameter of elements: An Array of ProbableElements.
- - Returns: A Double.
- */
- func probability(of elements: [ProbableElement]) -> Double
-
- /**
- The expected value of given elements based on a number of trials.
- - Parameter trials: An Int.
- - Parameter for elements: A list of ProbableElements.
- - Returns: A Double.
- */
- func expectedValue(trials: Int, for elements: ProbableElement...) -> Double
-
- /**
- The expected value of given elements based on a number of trials.
- - Parameter trials: An Int.
- - Parameter for elements: An Array of ProbableElements.
- - Returns: A Double.
- */
- func expectedValue(trials: Int, for elements: [ProbableElement]) -> Double
+ associatedtype ProbableElement: Equatable
+
+ /**
+ The instance count of elements.
+ - Parameter of elements: A list of ProbableElements
+ - Returns: An Int.
+ */
+ func count(of elements: ProbableElement...) -> Int
+
+ /**
+ The instance count of elements.
+ - Parameter of elements: An Array of ProbableElements.
+ - Returns: An Int.
+ */
+ func count(of elements: [ProbableElement]) -> Int
+
+ /**
+ The probability of given elements.
+ - Parameter of elements: A list of ProbableElements.
+ - Returns: A Double.
+ */
+ func probability(of elements: ProbableElement...) -> Double
+
+ /**
+ The probability of given elements.
+ - Parameter of elements: An Array of ProbableElements.
+ - Returns: A Double.
+ */
+ func probability(of elements: [ProbableElement]) -> Double
+
+ /**
+ The expected value of given elements based on a number of trials.
+ - Parameter trials: An Int.
+ - Parameter for elements: A list of ProbableElements.
+ - Returns: A Double.
+ */
+ func expectedValue(trials: Int, for elements: ProbableElement...) -> Double
+
+ /**
+ The expected value of given elements based on a number of trials.
+ - Parameter trials: An Int.
+ - Parameter for elements: An Array of ProbableElements.
+ - Returns: A Double.
+ */
+ func expectedValue(trials: Int, for elements: [ProbableElement]) -> Double
}
diff --git a/Sources/Queue.swift b/Sources/Queue.swift
index 9f030f2..877e7e2 100644
--- a/Sources/Queue.swift
+++ b/Sources/Queue.swift
@@ -24,110 +24,110 @@
*/
public struct Queue: CustomStringConvertible, Sequence {
- public typealias Iterator = AnyIterator
-
- /**
- :name: list
- :description: Underlying data structure.
- - returns: DoublyLinkedList
- */
- private var list: DoublyLinkedList
-
- /**
- :name: count
- :description: Total number of items in the Queue.
- - returns: Int
- */
- public var count: Int {
- return list.count
- }
-
- /**
- :name: peek
- :description: Get the element at the front of
- the Queue, and do not remove it.
- - returns: Element?
- */
- public var peek: Element? {
- return list.front
- }
-
- /**
- :name: isEmpty
- :description: A boolean of whether the Queue is empty.
- - returns: Bool
- */
- public var isEmpty: Bool {
- return list.isEmpty
- }
-
- /**
- :name: description
- :description: Conforms to the Printable Protocol.
- - returns: String
- */
- public var description: String {
- return list.description
- }
-
- /**
- :name: init
- :description: Constructor.
- */
- public init() {
- list = DoublyLinkedList()
- }
-
- //
- // :name: generate
- // :description: Conforms to the SequenceType Protocol. Returns
- // the next value in the sequence of nodes.
- // :returns: Queue.Generator
- //
- public func makeIterator() -> Iterator {
- return list.makeIterator()
- }
-
- /**
- :name: enqueue
- :description: Insert a new element at the back of the Queue.
- */
- mutating public func enqueue(_ element: Element) {
- list.insert(atBack: element)
- }
-
- /**
- :name: dequeue
- :description: Get and remove the element at the front
- of the Queue.
- - returns: Element?
- */
- mutating public func dequeue() -> Element? {
- return list.removeAtFront()
- }
-
- /**
- :name: removeAll
- :description: Remove all elements from the Queue.
- */
- mutating public func removeAll() {
- list.removeAll()
- }
-
- public static func +(lhs: Queue, rhs: Queue) -> Queue {
- var q = Queue()
- for x in lhs {
- q.enqueue(x)
+ public typealias Iterator = AnyIterator
+
+ /**
+ :name: list
+ :description: Underlying data structure.
+ - returns: DoublyLinkedList
+ */
+ private var list: DoublyLinkedList
+
+ /**
+ :name: count
+ :description: Total number of items in the Queue.
+ - returns: Int
+ */
+ public var count: Int {
+ return list.count
+ }
+
+ /**
+ :name: peek
+ :description: Get the element at the front of
+ the Queue, and do not remove it.
+ - returns: Element?
+ */
+ public var peek: Element? {
+ return list.front
+ }
+
+ /**
+ :name: isEmpty
+ :description: A boolean of whether the Queue is empty.
+ - returns: Bool
+ */
+ public var isEmpty: Bool {
+ return list.isEmpty
+ }
+
+ /**
+ :name: description
+ :description: Conforms to the Printable Protocol.
+ - returns: String
+ */
+ public var description: String {
+ return list.description
+ }
+
+ /**
+ :name: init
+ :description: Constructor.
+ */
+ public init() {
+ list = DoublyLinkedList()
}
- for x in rhs {
- q.enqueue(x)
+
+ //
+ // :name: generate
+ // :description: Conforms to the SequenceType Protocol. Returns
+ // the next value in the sequence of nodes.
+ // :returns: Queue.Generator
+ //
+ public func makeIterator() -> Iterator {
+ return list.makeIterator()
+ }
+
+ /**
+ :name: enqueue
+ :description: Insert a new element at the back of the Queue.
+ */
+ public mutating func enqueue(_ element: Element) {
+ list.insert(atBack: element)
+ }
+
+ /**
+ :name: dequeue
+ :description: Get and remove the element at the front
+ of the Queue.
+ - returns: Element?
+ */
+ public mutating func dequeue() -> Element? {
+ return list.removeAtFront()
}
- return q
- }
-
- public static func +=(lhs: inout Queue, rhs: Queue) {
- for x in rhs {
- lhs.enqueue(x)
+
+ /**
+ :name: removeAll
+ :description: Remove all elements from the Queue.
+ */
+ public mutating func removeAll() {
+ list.removeAll()
+ }
+
+ public static func + (lhs: Queue, rhs: Queue) -> Queue {
+ var q = Queue()
+ for x in lhs {
+ q.enqueue(x)
+ }
+ for x in rhs {
+ q.enqueue(x)
+ }
+ return q
+ }
+
+ public static func += (lhs: inout Queue, rhs: Queue) {
+ for x in rhs {
+ lhs.enqueue(x)
+ }
}
- }
}
diff --git a/Sources/RedBlackNode.swift b/Sources/RedBlackNode.swift
index f4e6746..1004fc1 100644
--- a/Sources/RedBlackNode.swift
+++ b/Sources/RedBlackNode.swift
@@ -24,96 +24,94 @@
*/
internal class RedBlackNode: Comparable, Equatable, CustomStringConvertible {
- /**
- :name: parent
- :description: A reference to the parent node of a given node.
- - returns: RedBlackNode!
- */
- internal var parent: RedBlackNode!
-
- /**
- :name: left
- :description: A reference to the left child node of a given node.
- - returns: RedBlackNode!
- */
- internal var left: RedBlackNode!
-
- /**
- :name: right
- :description: A reference to the right child node of a given node.
- - returns: RedBlackNode!
- */
- internal var right: RedBlackNode!
-
- /**
- :name: isRed
- :description: A boolean indicating whether te node is marked isRed or black.
- - returns: Bool
- */
- internal var isRed: Bool
-
- /**
- :name: order
- :description: Used to track the order statistic of a node, which maintains
- key order in the tree.
- - returns: Int
- */
- internal var order: Int
-
- /**
- :name: key
- :description: A reference to the key value of the node, which is what organizes
- a node in a given tree.
- - returns: Key!
- */
- internal var key: Key!
-
- /**
- :name: value
- :description: Satellite data stoisRed in the node.
- - returns: Value?
- */
- internal var value: Value?
-
- /**
- :name: description
- :description: Conforms to the Printable Protocol.
- - returns: String
- */
- internal var description: String {
- return "(\(String(describing: key)), \(String(describing: value)))"
- }
-
- /**
- :name: init
- :description: Constructor used for sentinel nodes.
- */
- internal init() {
- isRed = false
- order = 0
- }
-
- /**
- :name: init
- :description: Constructor used for nodes that store data.
- */
- internal init(parent: RedBlackNode, sentinel: RedBlackNode, key: Key, value: Value?) {
- self.key = key
- self.value = value
- self.parent = parent
- left = sentinel
- right = sentinel
- isRed = true
- order = 1
- }
-
- static func ==(lhs: RedBlackNode, rhs: RedBlackNode) -> Bool {
- return lhs.key == rhs.key
- }
-
- static func <(lhs: RedBlackNode, rhs: RedBlackNode) -> Bool {
- return lhs.key < rhs.key
- }
-}
+ /**
+ :name: parent
+ :description: A reference to the parent node of a given node.
+ - returns: RedBlackNode!
+ */
+ internal var parent: RedBlackNode!
+
+ /**
+ :name: left
+ :description: A reference to the left child node of a given node.
+ - returns: RedBlackNode!
+ */
+ internal var left: RedBlackNode!
+
+ /**
+ :name: right
+ :description: A reference to the right child node of a given node.
+ - returns: RedBlackNode!
+ */
+ internal var right: RedBlackNode!
+
+ /**
+ :name: isRed
+ :description: A boolean indicating whether te node is marked isRed or black.
+ - returns: Bool
+ */
+ internal var isRed: Bool
+
+ /**
+ :name: order
+ :description: Used to track the order statistic of a node, which maintains
+ key order in the tree.
+ - returns: Int
+ */
+ internal var order: Int
+
+ /**
+ :name: key
+ :description: A reference to the key value of the node, which is what organizes
+ a node in a given tree.
+ - returns: Key!
+ */
+ internal var key: Key!
+ /**
+ :name: value
+ :description: Satellite data stoisRed in the node.
+ - returns: Value?
+ */
+ internal var value: Value?
+ /**
+ :name: description
+ :description: Conforms to the Printable Protocol.
+ - returns: String
+ */
+ internal var description: String {
+ return "(\(String(describing: key)), \(String(describing: value)))"
+ }
+
+ /**
+ :name: init
+ :description: Constructor used for sentinel nodes.
+ */
+ internal init() {
+ isRed = false
+ order = 0
+ }
+
+ /**
+ :name: init
+ :description: Constructor used for nodes that store data.
+ */
+ internal init(parent: RedBlackNode, sentinel: RedBlackNode, key: Key, value: Value?) {
+ self.key = key
+ self.value = value
+ self.parent = parent
+ left = sentinel
+ right = sentinel
+ isRed = true
+ order = 1
+ }
+
+ static func == (lhs: RedBlackNode, rhs: RedBlackNode) -> Bool {
+ return lhs.key == rhs.key
+ }
+
+ static func < (lhs: RedBlackNode, rhs: RedBlackNode) -> Bool {
+ return lhs.key < rhs.key
+ }
+}
diff --git a/Sources/RedBlackTree.swift b/Sources/RedBlackTree.swift
index 61401d7..96339f6 100644
--- a/Sources/RedBlackTree.swift
+++ b/Sources/RedBlackTree.swift
@@ -24,876 +24,874 @@
*/
public struct RedBlackTree: Probable, Collection, BidirectionalCollection, CustomStringConvertible {
- public typealias Element = (key: Key, value: Value?)
- public typealias ProbableElement = Key
-
- /// Returns the position immediately after the given index.
- ///
- /// - Parameter i: A valid index of the collection. `i` must be less than
- /// `endIndex`.
- /// - Returns: The index value immediately after `i`.
- public func index(after i: Int) -> Int {
- return i + 1
- }
-
- public func index(before i: Int) -> Int {
- return i - 1
- }
-
- public typealias Iterator = AnyIterator
-
- /**
- Total number of elements within the RedBlackTree
- */
- public internal(set) var count = 0
-
- /**
- :name: sentinel
- :description: A node used to mark the end of a path in the tree.
- - returns: RedBlackNode
- */
- internal private(set) var sentinel: RedBlackNode
-
- /**
- :name: root
- :description: The root of the tree data structure.
- - returns: RedBlackNode
- */
- internal private(set) var root: RedBlackNode
-
- /**
- :name: isUniquelyKeyed
- :description: A boolean used to indicate whether to allow the
- tree to store non-unique key values or only unique
- key values.
- - returns: Bool
- */
- public private(set) var isUniquelyKeyed: Bool
-
- /**
- :name: description
- :description: Conforms to the Printable Protocol. Outputs the
- data in the Tree in a readable format.
- - returns: String
- */
- public var description: String {
- return "[" + map { "\($0)" }.joined(separator: ", ") + "]"
- }
-
- /**
- :name: startIndex
- :description: Conforms to the Collection Protocol.
- - returns: Int
- */
- public var startIndex: Int {
- return 0
- }
-
- /**
- :name: endIndex
- :description: Conforms to the Collection Protocol.
- - returns: Int
- */
- public var endIndex: Int {
- return count
- }
-
- /**
- :name: first
- :description: Get the first node value in the tree, this is
- the first node based on the order of keys where
- k1 <= k2 <= K3 ... <= Kn
- - returns: Element?
- */
- public var first: Element? {
- guard 0 < count else {
- return nil
- }
-
- return self[0]
- }
-
- /**
- :name: last
- :description: Get the last node value in the tree, this is
- the last node based on the order of keys where
- k1 <= k2 <= K3 ... <= Kn
- - returns: Element?
- */
- public var last: Element? {
- guard 0 < count else {
- return nil
- }
-
- return self[count - 1]
- }
-
- /// Retrieves an Array of the key values in order.
- public var keys: [Key] {
- return map { $0.key }
- }
-
- /// Retrieves an Array of the values that are sorted based.
- public var values: [Value] {
- return compactMap { $0.value }
- }
-
- /**
- :name: init
- :description: Constructor where the tree is guaranteed to store
- non-unique keys.
- */
- public init() {
- isUniquelyKeyed = false
- sentinel = RedBlackNode()
- root = sentinel
- }
-
- /**
- :name: init
- :description: Constructor where the tree is optionally allowed
- to store uniqe or non-unique keys.
- - parameter uniqueKeys: Bool Set the keys to be unique.
- */
- public init(uniqueKeys: Bool) {
- isUniquelyKeyed = uniqueKeys
- sentinel = RedBlackNode()
- root = sentinel
- }
-
- public func _customIndexOfEquatableElement(_ element: Key) -> Int?? {
- return nil
- }
-
- //
- // :name: generate
- // :description: Conforms to the SequenceType Protocol. Returns
- // the next value in the sequence of nodes using
- // index values [0...n-1].
- // :returns: RedBlackTree.Generator
- //
- public func makeIterator() -> RedBlackTree.Iterator {
- var i = indices.makeIterator()
- return AnyIterator { i.next().map { self[$0] } }
- }
-
- /**
- Conforms to Probable protocol.
- */
- public func count(of keys: Key...) -> Int {
- return count(of: keys)
- }
-
- /**
- Conforms to Probable protocol.
- */
- public func count(of keys: [Key]) -> Int {
- var c = 0
-
- for k in keys {
- internalCount(k, node: root, count: &c)
- }
-
- return c
- }
-
- /**
- The probability of elements.
- */
- public func probability(of keys: Key...) -> Double {
- return probability(of: keys)
- }
-
- /**
- The probability of elements.
- */
- public func probability(of keys: [Key]) -> Double {
- return 0 == count ? 0 : Double(count(of: keys)) / Double(count)
- }
-
- /**
- The probability of elements.
- */
- public func probability(execute block: (Key, Value?) -> Bool) -> Double {
- if 0 == count {
- return 0
- }
-
- var c = 0
-
- for (k, v) in self {
- if block(k, v) {
- c += 1
- }
- }
-
- return Double(c) / Double(count)
- }
-
- /**
- The expected value of elements.
- */
- public func expectedValue(trials: Int, for keys: Key...) -> Double {
- return expectedValue(trials: trials, for: keys)
- }
-
- /**
- The expected value of elements.
- */
- public func expectedValue(trials: Int, for keys: [Key]) -> Double {
- return Double(trials) * probability(of: keys)
- }
-
- /**
- :name: insert
- :description: Insert a key / value pair.
- - returns: Bool
- */
- @discardableResult
- mutating public func insert(value: Value?, for key: Key) -> Bool {
- return sentinel !== internalInsert(key, value: value)
- }
-
- /**
- :name: insert
- :description: Inserts a list of (Key, Value?) pairs.
- - parameter nodes: (Key, Value?)... Elements to insert.
- */
- mutating public func insert(_ nodes: (Key, Value?)...) {
- insert(nodes)
- }
-
- /**
- :name: insert
- :description: Inserts an array of (Key, Value?) pairs.
- - parameter nodes: [(Key, Value?)] Elements to insert.
- */
- mutating public func insert(_ nodes: [(Key, Value?)]) {
- for (k, v) in nodes {
- insert(value: v, for: k)
- }
- }
-
- /**
- :name: removeValueForKeys
- :description: Removes a node from the tree based on the key value given.
- If the tree allows non-unique keys, then all keys matching
- the given key value will be removed.
- - returns: RedBlackTree?
- */
- mutating public func removeValue(for keys: Key...) {
- return removeValue(for: keys)
- }
-
- /**
- :name: removeValueForKeys
- :description: Removes a key / value pairs from the tree based on the key given.
- If the tree allows non-unique keys, then all keys matching
- the given key will be removed.
- - returns: RedBlackTree?
- */
- mutating public func removeValue(for keys: [Key]) {
- for x in keys {
- var z = internalRemoveValueForKey(x)
-
- while sentinel !== z {
- z = internalRemoveValueForKey(x)
- }
- }
- }
-
- /**
- :name: removeValueForKey
- :description: Removes a single instance of a value for a key. This is
- important when using non-unique keys.
- - returns: Value?
- */
- @discardableResult
- mutating public func removeInstanceValueForKey(_ key: Key) -> Value? {
- return internalRemoveValueForKey(key).value
- }
-
- /**
- :name: removeAll
- :description: Remove all nodes from the tree.
- */
- mutating public func removeAll() {
- while sentinel !== root {
- internalRemoveValueForKey(root.key)
- }
- }
-
- /**
- :name: updateValue
- :description: Updates a node for the given key value.
- If the tree allows non-unique keys, then all keys matching
- the given key value will be updated.
- */
- mutating public func update(value: Value?, for key: Key) {
- internalUpdateValue(value, for: key, node: root)
- }
-
- /**
- :name: findValueForKey
- :description: Finds the first instance in a non-unique tree and only instance
- in isUniquelyKeyed tree of a given keyed node.
- - returns: Value?
- */
- public func findValue(for key: Key) -> Value? {
- return internalFindNodeForKey(key).value
- }
-
- /**
- :name: findLowerValue
- :description: Finds instance with key that is lower or equal input key
- - returns: Value?
- */
- public func findLowerValue(for key: Key) -> Value? {
- return internalFindLowerForKey(key).value
- }
-
- /**
- :name: findCeilingValue
- :description: Finds instance with key that is larger or equal input key
- - returns: Value?
- */
- public func findCeilingValue(for key: Key) -> Value? {
- return internalFindCeilingForKey(key).value
- }
-
- /**
- Returns the Key value at a given position.
- - Parameter position: An Int.
- - Returns: A Key.
- */
- public subscript(position: Int) -> Key {
- return self[position].key
- }
-
- /**
- :name: operator [0...count - 1]
- :description: Allows array like access of the index.
- Items are kept in order, so when iterating
- through the items, they are returned in their
- ordeisRed form.
- - returns: (key: Key, value: Value?)
- */
- public subscript(index: Int) -> (key: Key, value: Value?) {
- get {
- let x = internalSelect(root, order: index + 1)
- return (x.key, x.value)
- }
- set(element) {
- internalUpdateValue(element.value, for: element.key, node: root)
- }
- }
-
- /**
- :name: operator ["key1"..."keyN"]
- :description: Property key mapping. If the key type is a
- String, this feature allows access like a
- Dictionary.
- - returns: Value?
- */
- public subscript(key: Key) -> Value? {
- get {
- return internalFindNodeForKey(key).value
- }
- set(value) {
- if sentinel === internalFindNodeForKey(key) {
- _ = internalInsert(key, value: value)
- } else {
- update(value: value, for: key)
- }
- }
- }
-
- /**
- :name: internalFindLowerForKey
- :description: Finds a node with a key that is equal or less that given.
- - returns: RedBlackNode
- */
- private func internalFindLowerForKey(_ key: Key) -> RedBlackNode {
- var z = root
- var max = sentinel
-
- while z !== sentinel {
- if key > z.key {
- max = z
- }
- if key == z.key {
+ public typealias Element = (key: Key, value: Value?)
+ public typealias ProbableElement = Key
+
+ /// Returns the position immediately after the given index.
+ ///
+ /// - Parameter i: A valid index of the collection. `i` must be less than
+ /// `endIndex`.
+ /// - Returns: The index value immediately after `i`.
+ public func index(after i: Int) -> Int {
+ return i + 1
+ }
+
+ public func index(before i: Int) -> Int {
+ return i - 1
+ }
+
+ public typealias Iterator = AnyIterator
+
+ /**
+ Total number of elements within the RedBlackTree
+ */
+ public internal(set) var count = 0
+
+ /**
+ :name: sentinel
+ :description: A node used to mark the end of a path in the tree.
+ - returns: RedBlackNode
+ */
+ internal private(set) var sentinel: RedBlackNode
+
+ /**
+ :name: root
+ :description: The root of the tree data structure.
+ - returns: RedBlackNode
+ */
+ internal private(set) var root: RedBlackNode
+
+ /**
+ :name: isUniquelyKeyed
+ :description: A boolean used to indicate whether to allow the
+ tree to store non-unique key values or only unique
+ key values.
+ - returns: Bool
+ */
+ public private(set) var isUniquelyKeyed: Bool
+
+ /**
+ :name: description
+ :description: Conforms to the Printable Protocol. Outputs the
+ data in the Tree in a readable format.
+ - returns: String
+ */
+ public var description: String {
+ return "[" + map { "\($0)" }.joined(separator: ", ") + "]"
+ }
+
+ /**
+ :name: startIndex
+ :description: Conforms to the Collection Protocol.
+ - returns: Int
+ */
+ public var startIndex: Int {
+ return 0
+ }
+
+ /**
+ :name: endIndex
+ :description: Conforms to the Collection Protocol.
+ - returns: Int
+ */
+ public var endIndex: Int {
+ return count
+ }
+
+ /**
+ :name: first
+ :description: Get the first node value in the tree, this is
+ the first node based on the order of keys where
+ k1 <= k2 <= K3 ... <= Kn
+ - returns: Element?
+ */
+ public var first: Element? {
+ guard count > 0 else {
+ return nil
+ }
+
+ return self[0]
+ }
+
+ /**
+ :name: last
+ :description: Get the last node value in the tree, this is
+ the last node based on the order of keys where
+ k1 <= k2 <= K3 ... <= Kn
+ - returns: Element?
+ */
+ public var last: Element? {
+ guard count > 0 else {
+ return nil
+ }
+
+ return self[count - 1]
+ }
+
+ /// Retrieves an Array of the key values in order.
+ public var keys: [Key] {
+ return map { $0.key }
+ }
+
+ /// Retrieves an Array of the values that are sorted based.
+ public var values: [Value] {
+ return compactMap { $0.value }
+ }
+
+ /**
+ :name: init
+ :description: Constructor where the tree is guaranteed to store
+ non-unique keys.
+ */
+ public init() {
+ isUniquelyKeyed = false
+ sentinel = RedBlackNode()
+ root = sentinel
+ }
+
+ /**
+ :name: init
+ :description: Constructor where the tree is optionally allowed
+ to store uniqe or non-unique keys.
+ - parameter uniqueKeys: Bool Set the keys to be unique.
+ */
+ public init(uniqueKeys: Bool) {
+ isUniquelyKeyed = uniqueKeys
+ sentinel = RedBlackNode()
+ root = sentinel
+ }
+
+ public func _customIndexOfEquatableElement(_: Key) -> Int?? {
+ return nil
+ }
+
+ //
+ // :name: generate
+ // :description: Conforms to the SequenceType Protocol. Returns
+ // the next value in the sequence of nodes using
+ // index values [0...n-1].
+ // :returns: RedBlackTree.Generator
+ //
+ public func makeIterator() -> RedBlackTree.Iterator {
+ var i = indices.makeIterator()
+ return AnyIterator { i.next().map { self[$0] } }
+ }
+
+ /**
+ Conforms to Probable protocol.
+ */
+ public func count(of keys: Key...) -> Int {
+ return count(of: keys)
+ }
+
+ /**
+ Conforms to Probable protocol.
+ */
+ public func count(of keys: [Key]) -> Int {
+ var c = 0
+
+ for k in keys {
+ internalCount(k, node: root, count: &c)
+ }
+
+ return c
+ }
+
+ /**
+ The probability of elements.
+ */
+ public func probability(of keys: Key...) -> Double {
+ return probability(of: keys)
+ }
+
+ /**
+ The probability of elements.
+ */
+ public func probability(of keys: [Key]) -> Double {
+ return count == 0 ? 0 : Double(count(of: keys)) / Double(count)
+ }
+
+ /**
+ The probability of elements.
+ */
+ public func probability(execute block: (Key, Value?) -> Bool) -> Double {
+ if count == 0 {
+ return 0
+ }
+
+ var c = 0
+
+ for (k, v) in self {
+ if block(k, v) {
+ c += 1
+ }
+ }
+
+ return Double(c) / Double(count)
+ }
+
+ /**
+ The expected value of elements.
+ */
+ public func expectedValue(trials: Int, for keys: Key...) -> Double {
+ return expectedValue(trials: trials, for: keys)
+ }
+
+ /**
+ The expected value of elements.
+ */
+ public func expectedValue(trials: Int, for keys: [Key]) -> Double {
+ return Double(trials) * probability(of: keys)
+ }
+
+ /**
+ :name: insert
+ :description: Insert a key / value pair.
+ - returns: Bool
+ */
+ @discardableResult
+ public mutating func insert(value: Value?, for key: Key) -> Bool {
+ return sentinel !== internalInsert(key, value: value)
+ }
+
+ /**
+ :name: insert
+ :description: Inserts a list of (Key, Value?) pairs.
+ - parameter nodes: (Key, Value?)... Elements to insert.
+ */
+ public mutating func insert(_ nodes: (Key, Value?)...) {
+ insert(nodes)
+ }
+
+ /**
+ :name: insert
+ :description: Inserts an array of (Key, Value?) pairs.
+ - parameter nodes: [(Key, Value?)] Elements to insert.
+ */
+ public mutating func insert(_ nodes: [(Key, Value?)]) {
+ for (k, v) in nodes {
+ insert(value: v, for: k)
+ }
+ }
+
+ /**
+ :name: removeValueForKeys
+ :description: Removes a node from the tree based on the key value given.
+ If the tree allows non-unique keys, then all keys matching
+ the given key value will be removed.
+ - returns: RedBlackTree?
+ */
+ public mutating func removeValue(for keys: Key...) {
+ return removeValue(for: keys)
+ }
+
+ /**
+ :name: removeValueForKeys
+ :description: Removes a key / value pairs from the tree based on the key given.
+ If the tree allows non-unique keys, then all keys matching
+ the given key will be removed.
+ - returns: RedBlackTree?
+ */
+ public mutating func removeValue(for keys: [Key]) {
+ for x in keys {
+ var z = internalRemoveValueForKey(x)
+
+ while sentinel !== z {
+ z = internalRemoveValueForKey(x)
+ }
+ }
+ }
+
+ /**
+ :name: removeValueForKey
+ :description: Removes a single instance of a value for a key. This is
+ important when using non-unique keys.
+ - returns: Value?
+ */
+ @discardableResult
+ public mutating func removeInstanceValueForKey(_ key: Key) -> Value? {
+ return internalRemoveValueForKey(key).value
+ }
+
+ /**
+ :name: removeAll
+ :description: Remove all nodes from the tree.
+ */
+ public mutating func removeAll() {
+ while sentinel !== root {
+ internalRemoveValueForKey(root.key)
+ }
+ }
+
+ /**
+ :name: updateValue
+ :description: Updates a node for the given key value.
+ If the tree allows non-unique keys, then all keys matching
+ the given key value will be updated.
+ */
+ public mutating func update(value: Value?, for key: Key) {
+ internalUpdateValue(value, for: key, node: root)
+ }
+
+ /**
+ :name: findValueForKey
+ :description: Finds the first instance in a non-unique tree and only instance
+ in isUniquelyKeyed tree of a given keyed node.
+ - returns: Value?
+ */
+ public func findValue(for key: Key) -> Value? {
+ return internalFindNodeForKey(key).value
+ }
+
+ /**
+ :name: findLowerValue
+ :description: Finds instance with key that is lower or equal input key
+ - returns: Value?
+ */
+ public func findLowerValue(for key: Key) -> Value? {
+ return internalFindLowerForKey(key).value
+ }
+
+ /**
+ :name: findCeilingValue
+ :description: Finds instance with key that is larger or equal input key
+ - returns: Value?
+ */
+ public func findCeilingValue(for key: Key) -> Value? {
+ return internalFindCeilingForKey(key).value
+ }
+
+ /**
+ Returns the Key value at a given position.
+ - Parameter position: An Int.
+ - Returns: A Key.
+ */
+ public subscript(position: Int) -> Key {
+ return self[position].key
+ }
+
+ /**
+ :name: operator [0...count - 1]
+ :description: Allows array like access of the index.
+ Items are kept in order, so when iterating
+ through the items, they are returned in their
+ ordeisRed form.
+ - returns: (key: Key, value: Value?)
+ */
+ public subscript(index: Int) -> (key: Key, value: Value?) {
+ get {
+ let x = internalSelect(root, order: index + 1)
+ return (x.key, x.value)
+ }
+ set(element) {
+ internalUpdateValue(element.value, for: element.key, node: root)
+ }
+ }
+
+ /**
+ :name: operator ["key1"..."keyN"]
+ :description: Property key mapping. If the key type is a
+ String, this feature allows access like a
+ Dictionary.
+ - returns: Value?
+ */
+ public subscript(key: Key) -> Value? {
+ get {
+ return internalFindNodeForKey(key).value
+ }
+ set(value) {
+ if sentinel === internalFindNodeForKey(key) {
+ _ = internalInsert(key, value: value)
+ } else {
+ update(value: value, for: key)
+ }
+ }
+ }
+
+ /**
+ :name: internalFindLowerForKey
+ :description: Finds a node with a key that is equal or less that given.
+ - returns: RedBlackNode
+ */
+ private func internalFindLowerForKey(_ key: Key) -> RedBlackNode {
+ var z = root
+ var max = sentinel
+
+ while z !== sentinel {
+ if key > z.key {
+ max = z
+ }
+ if key == z.key {
+ return z
+ }
+ z = key < z.key as Key ? z.left : z.right
+ }
+ return max
+ }
+
+ /**
+ :name: internalFindCeilingForKey
+ :description: Finds a node with a key that is equal or larger that given.
+ - returns: RedBlackNode
+ */
+ private func internalFindCeilingForKey(_ key: Key) -> RedBlackNode {
+ var z = root
+ var min = sentinel
+
+ while z !== sentinel {
+ if key < z.key {
+ min = z
+ }
+ if key == z.key {
+ return z
+ }
+ z = key < z.key as Key ? z.left : z.right
+ }
+ return min
+ }
+
+ /**
+ :name: indexOf
+ :description: Returns the Index of a given member, or nil if the member is not present in the set.
+ - returns: Int
+ */
+ public func index(of key: Key) -> Int {
+ let x = internalFindNodeForKey(key)
+ return sentinel === x ? -1 : internalOrder(x) - 1
+ }
+
+ /**
+ :name: internalInsert
+ :description: Insert a new node with the given key and value.
+ - returns: RedBlackNode
+ */
+ private mutating func internalInsert(_ key: Key, value: Value?) -> RedBlackNode {
+ if isUniquelyKeyed, sentinel !== internalFindNodeForKey(key) {
+ return sentinel
+ }
+
+ var y = sentinel
+ var x = root
+
+ while x !== sentinel {
+ y = x
+ y.order += 1
+ x = key < x.key as Key ? x.left : x.right
+ }
+
+ let z = RedBlackNode(parent: y, sentinel: sentinel, key: key, value: value)
+
+ if y === sentinel {
+ root = z
+ } else if key < y.key as Key {
+ y.left = z
+ } else {
+ y.right = z
+ }
+
+ insertCleanUp(z)
+ count += 1
return z
- }
- z = key < z.key as Key ? z.left : z.right
- }
- return max
- }
-
- /**
- :name: internalFindCeilingForKey
- :description: Finds a node with a key that is equal or larger that given.
- - returns: RedBlackNode
- */
- private func internalFindCeilingForKey(_ key: Key) -> RedBlackNode {
- var z = root
- var min = sentinel
-
- while z !== sentinel {
- if key < z.key {
- min = z
- }
- if key == z.key {
+ }
+
+ /**
+ :name: insertCleanUp
+ :description: The clean up procedure needed to maintain the RedBlackTree balance.
+ - returns: RedBlackNode
+ */
+ private mutating func insertCleanUp(_ node: RedBlackNode) {
+ var z = node
+ while z.parent.isRed {
+ if z.parent === z.parent.parent.left {
+ let y = z.parent.parent.right!
+ // violation 1, parent child relationship re to isRed
+ if y.isRed {
+ z.parent.isRed = false
+ y.isRed = false
+ z.parent.parent.isRed = true
+ z = z.parent.parent
+ } else {
+ // case 2, parent is isRed, uncle is black
+ if z === z.parent.right {
+ z = z.parent
+ leftRotate(z)
+ }
+ // case 3, balance colours
+ z.parent.isRed = false
+ z.parent.parent.isRed = true
+ rightRotate(z.parent.parent)
+ }
+ } else {
+ // symetric
+ let y = z.parent.parent.left!
+ // violation 1, parent child relationship re to isRed
+ if y.isRed {
+ z.parent.isRed = false
+ y.isRed = false
+ z.parent.parent.isRed = true
+ z = z.parent.parent
+ } else {
+ // case 2, parent is isRed, uncle is black
+ if z === z.parent.left {
+ z = z.parent
+ rightRotate(z)
+ }
+ // case 3, balance colours
+ z.parent.isRed = false
+ z.parent.parent.isRed = true
+ leftRotate(z.parent.parent)
+ }
+ }
+ }
+ root.isRed = false
+ }
+
+ /**
+ :name: internalRemoveValueForKey
+ :description: Removes a node with the given key value and returns that
+ node. If the value does not exist, the sentinel is returned.
+ - returns: RedBlackNode
+ */
+ @discardableResult
+ private mutating func internalRemoveValueForKey(_ key: Key) -> RedBlackNode {
+ let z = internalFindNodeForKey(key)
+ if z === sentinel {
+ return sentinel
+ }
+
+ if z !== root {
+ var t = z.parent!
+ while t !== root {
+ t.order -= 1
+ t = t.parent
+ }
+ root.order -= 1
+ }
+
+ var x: RedBlackNode!
+ var y = z
+ var isRed = y.isRed
+
+ if z.left === sentinel {
+ x = z.right
+ transplant(z, v: z.right)
+ } else if z.right === sentinel {
+ x = z.left
+ transplant(z, v: z.left)
+ } else {
+ y = minimum(z.right)
+ isRed = y.isRed
+ x = y.right
+ if y.parent === z {
+ x.parent = y
+ } else {
+ transplant(y, v: y.right)
+ y.right = z.right
+ y.right.parent = y
+ var t = x.parent!
+ while t !== y {
+ t.order -= 1
+ t = t.parent
+ }
+ y.order = y.left.order + 1
+ }
+ transplant(z, v: y)
+ y.left = z.left
+ y.left.parent = y
+ y.isRed = z.isRed
+ y.order = y.left.order + y.right.order + 1
+ }
+ if !isRed {
+ removeCleanUp(x)
+ }
+ count -= 1
return z
- }
- z = key < z.key as Key ? z.left : z.right
- }
- return min
- }
-
- /**
- :name: indexOf
- :description: Returns the Index of a given member, or nil if the member is not present in the set.
- - returns: Int
- */
- public func index(of key: Key) -> Int {
- let x = internalFindNodeForKey(key)
- return sentinel === x ? -1 : internalOrder(x) - 1
- }
-
- /**
- :name: internalInsert
- :description: Insert a new node with the given key and value.
- - returns: RedBlackNode
- */
- mutating private func internalInsert(_ key: Key, value: Value?) -> RedBlackNode {
- if isUniquelyKeyed && sentinel !== internalFindNodeForKey(key) {
- return sentinel;
- }
-
- var y = sentinel
- var x = root
-
- while x !== sentinel {
- y = x
- y.order += 1
- x = key < x.key as Key ? x.left : x.right
- }
-
- let z = RedBlackNode(parent: y, sentinel: sentinel, key: key, value: value)
-
- if y === sentinel {
- root = z
- } else if key < y.key as Key {
- y.left = z
- } else {
- y.right = z
- }
-
- insertCleanUp(z)
- count += 1
- return z
- }
-
- /**
- :name: insertCleanUp
- :description: The clean up procedure needed to maintain the RedBlackTree balance.
- - returns: RedBlackNode
- */
- mutating private func insertCleanUp(_ node: RedBlackNode) {
- var z = node
- while z.parent.isRed {
- if z.parent === z.parent.parent.left {
- let y = z.parent.parent.right!
- // violation 1, parent child relationship re to isRed
- if y.isRed {
- z.parent.isRed = false
- y.isRed = false
- z.parent.parent.isRed = true
- z = z.parent.parent
+ }
+
+ /**
+ :name: removeCleanUp
+ :description: After a successful removal of a node, the RedBlackTree
+ is rebalanced by this method.
+ */
+ private mutating func removeCleanUp(_ node: RedBlackNode) {
+ var x = node
+ while x !== root, !x.isRed {
+ if x === x.parent.left {
+ var y = x.parent.right!
+ if y.isRed {
+ y.isRed = false
+ x.parent.isRed = true
+ leftRotate(x.parent)
+ y = x.parent.right
+ }
+ if !y.left.isRed, !y.right.isRed {
+ y.isRed = true
+ x = x.parent
+ } else {
+ if !y.right.isRed {
+ y.left.isRed = false
+ y.isRed = true
+ rightRotate(y)
+ y = x.parent.right
+ }
+ y.isRed = x.parent.isRed
+ x.parent.isRed = false
+ y.right.isRed = false
+ leftRotate(x.parent)
+ x = root
+ }
+ } else { // symetric left and right
+ var y = x.parent.left!
+ if y.isRed {
+ y.isRed = false
+ x.parent.isRed = true
+ rightRotate(x.parent)
+ y = x.parent.left
+ }
+ if !y.right.isRed, !y.left.isRed {
+ y.isRed = true
+ x = x.parent
+ } else {
+ if !y.left.isRed {
+ y.right.isRed = false
+ y.isRed = true
+ leftRotate(y)
+ y = x.parent.left
+ }
+ y.isRed = x.parent.isRed
+ x.parent.isRed = false
+ y.left.isRed = false
+ rightRotate(x.parent)
+ x = root
+ }
+ }
+ }
+ x.isRed = false
+ }
+
+ /**
+ :name: minimum
+ :description: Finds the minimum keyed node.
+ - returns: RedBlackNode
+ */
+ private func minimum(_ node: RedBlackNode) -> RedBlackNode {
+ var x = node
+ var y = sentinel
+ while x !== sentinel {
+ y = x
+ x = x.left
+ }
+ return y
+ }
+
+ /**
+ :name: transplant
+ :description: Swaps two subTrees in the tree.
+ */
+ private mutating func transplant(_ u: RedBlackNode, v: RedBlackNode) {
+ if u.parent === sentinel {
+ root = v
+ } else if u === u.parent.left {
+ u.parent.left = v
} else {
- // case 2, parent is isRed, uncle is black
- if z === z.parent.right {
- z = z.parent
- leftRotate(z)
- }
- // case 3, balance colours
- z.parent.isRed = false
- z.parent.parent.isRed = true
- rightRotate(z.parent.parent)
- }
- } else {
- // symetric
- let y = z.parent.parent.left!
- // violation 1, parent child relationship re to isRed
- if y.isRed {
- z.parent.isRed = false
- y.isRed = false
- z.parent.parent.isRed = true
- z = z.parent.parent
+ u.parent.right = v
+ }
+ v.parent = u.parent
+ }
+
+ /**
+ :name: leftRotate
+ :description: Rotates the nodes to satisfy the RedBlackTree
+ balance property.
+ */
+ private mutating func leftRotate(_ x: RedBlackNode) {
+ let y = x.right!
+
+ x.right = y.left
+ if sentinel !== y.left {
+ y.left.parent = x
+ }
+
+ y.parent = x.parent
+
+ if sentinel === x.parent {
+ root = y
+ } else if x === x.parent.left {
+ x.parent.left = y
} else {
- // case 2, parent is isRed, uncle is black
- if z === z.parent.left {
- z = z.parent
- rightRotate(z)
- }
- // case 3, balance colours
- z.parent.isRed = false
- z.parent.parent.isRed = true
- leftRotate(z.parent.parent)
- }
- }
- }
- root.isRed = false
- }
-
- /**
- :name: internalRemoveValueForKey
- :description: Removes a node with the given key value and returns that
- node. If the value does not exist, the sentinel is returned.
- - returns: RedBlackNode
- */
- @discardableResult
- mutating private func internalRemoveValueForKey(_ key: Key) -> RedBlackNode {
- let z = internalFindNodeForKey(key)
- if z === sentinel {
- return sentinel
- }
-
- if z !== root {
- var t = z.parent!
- while t !== root {
- t.order -= 1
- t = t.parent
- }
- root.order -= 1
- }
-
- var x: RedBlackNode!
- var y = z
- var isRed = y.isRed
-
- if z.left === sentinel {
- x = z.right
- transplant(z, v: z.right)
- } else if z.right === sentinel {
- x = z.left
- transplant(z, v: z.left)
- } else {
- y = minimum(z.right)
- isRed = y.isRed
- x = y.right
- if y.parent === z {
+ x.parent.right = y
+ }
+
+ y.left = x
x.parent = y
- } else {
- transplant(y, v: y.right)
- y.right = z.right
- y.right.parent = y
- var t = x.parent!
- while t !== y {
- t.order -= 1
- t = t.parent
- }
- y.order = y.left.order + 1
- }
- transplant(z, v: y)
- y.left = z.left
- y.left.parent = y
- y.isRed = z.isRed
- y.order = y.left.order + y.right.order + 1
- }
- if !isRed {
- removeCleanUp(x)
- }
- count -= 1
- return z
- }
-
- /**
- :name: removeCleanUp
- :description: After a successful removal of a node, the RedBlackTree
- is rebalanced by this method.
- */
- mutating private func removeCleanUp(_ node: RedBlackNode) {
- var x = node
- while x !== root && !x.isRed {
- if x === x.parent.left {
- var y = x.parent.right!
- if y.isRed {
- y.isRed = false
- x.parent.isRed = true
- leftRotate(x.parent)
- y = x.parent.right
- }
- if !y.left.isRed && !y.right.isRed {
- y.isRed = true
- x = x.parent
- } else {
- if !y.right.isRed {
- y.left.isRed = false
- y.isRed = true
- rightRotate(y)
- y = x.parent.right
- }
- y.isRed = x.parent.isRed
- x.parent.isRed = false
- y.right.isRed = false
- leftRotate(x.parent)
- x = root
- }
- } else { // symetric left and right
- var y = x.parent.left!
- if y.isRed {
- y.isRed = false
- x.parent.isRed = true
- rightRotate(x.parent)
- y = x.parent.left
- }
- if !y.right.isRed && !y.left.isRed {
- y.isRed = true
- x = x.parent
+ y.order = x.order
+ x.order = x.left.order + x.right.order + 1
+ }
+
+ /**
+ :name: rightRotate
+ :description: Rotates the nodes to satisfy the RedBlackTree
+ balance property.
+ */
+ private mutating func rightRotate(_ y: RedBlackNode) {
+ let x = y.left!
+
+ y.left = x.right
+ if sentinel !== x.right {
+ x.right.parent = y
+ }
+
+ x.parent = y.parent
+
+ if sentinel === y.parent {
+ root = x
+ } else if y === y.parent.right {
+ y.parent.right = x
} else {
- if !y.left.isRed {
- y.right.isRed = false
- y.isRed = true
- leftRotate(y)
- y = x.parent.left
- }
- y.isRed = x.parent.isRed
- x.parent.isRed = false
- y.left.isRed = false
- rightRotate(x.parent)
- x = root
- }
- }
- }
- x.isRed = false
- }
-
- /**
- :name: minimum
- :description: Finds the minimum keyed node.
- - returns: RedBlackNode
- */
- private func minimum(_ node: RedBlackNode) -> RedBlackNode {
- var x = node
- var y = sentinel
- while x !== sentinel {
- y = x
- x = x.left
- }
- return y
- }
-
- /**
- :name: transplant
- :description: Swaps two subTrees in the tree.
- */
- mutating private func transplant(_ u: RedBlackNode, v: RedBlackNode) {
- if u.parent === sentinel {
- root = v
- } else if u === u.parent.left {
- u.parent.left = v
- } else {
- u.parent.right = v
- }
- v.parent = u.parent
- }
-
- /**
- :name: leftRotate
- :description: Rotates the nodes to satisfy the RedBlackTree
- balance property.
- */
- mutating private func leftRotate(_ x: RedBlackNode) {
- let y = x.right!
-
- x.right = y.left
- if sentinel !== y.left {
- y.left.parent = x
- }
-
- y.parent = x.parent
-
- if sentinel === x.parent {
- root = y
- } else if x === x.parent.left {
- x.parent.left = y
- } else {
- x.parent.right = y
- }
-
- y.left = x
- x.parent = y
- y.order = x.order
- x.order = x.left.order + x.right.order + 1
- }
-
- /**
- :name: rightRotate
- :description: Rotates the nodes to satisfy the RedBlackTree
- balance property.
- */
- mutating private func rightRotate(_ y: RedBlackNode) {
- let x = y.left!
-
- y.left = x.right
- if sentinel !== x.right {
- x.right.parent = y
- }
-
- x.parent = y.parent
-
- if sentinel === y.parent {
- root = x
- } else if y === y.parent.right {
- y.parent.right = x
- } else {
- y.parent.left = x
- }
-
- x.right = y
- y.parent = x
- x.order = y.order
- y.order = y.left.order + y.right.order + 1
- }
-
- /**
- :name: internalFindNodeForKey
- :description: Finds a node with a given key value.
- - returns: RedBlackNode
- */
- private func internalFindNodeForKey(_ key: Key) -> RedBlackNode {
- var z = root
- while z !== sentinel {
- if key == z.key {
- return z
- }
- z = key < z.key as Key ? z.left : z.right
- }
- return sentinel
- }
-
- /**
- :name: internalSelect
- :description: Internally searches for a node by the order statistic value.
- - returns: RedBlackNode
- */
- private func internalSelect(_ x: RedBlackNode, order: Int) -> RedBlackNode {
- validateOrder(order)
-
- let r = x.left.order + 1
-
- if order == r {
- return x
- } else if order < r {
- return internalSelect(x.left, order: order)
- }
-
- return internalSelect(x.right, order: order - r)
- }
-
- /**
- :name: internalCount
- :description: Traverses the Tree while counting number of times a key appears.
- */
- private func internalCount(_ key: Key, node: RedBlackNode, count: inout Int) {
- if sentinel !== node {
- if key == node.key {
- count += 1
- }
-
- internalCount(key, node: node.left, count: &count)
- internalCount(key, node: node.right, count: &count)
- }
- }
-
- /**
- :name: internalUpdateValue
- :description: Traverses the Tree and updates all the values that match the key.
- */
- private func internalUpdateValue(_ value: Value?, for key: Key, node: RedBlackNode) {
- if node !== sentinel {
- if key == node.key {
- node.value = value
- }
-
- internalUpdateValue(value, for: key, node: node.left)
- internalUpdateValue(value, for: key, node: node.right)
- }
- }
-
- /**
- :name: internalOrder
- :description: Traverses the Tree for the internal order statistic of a key.
- - returns: Int
- */
- private func internalOrder(_ node: RedBlackNode) -> Int {
- var x = node
- var r: Int = x.left.order + 1
-
- while root !== x {
- if x.parent.right === x {
- r += x.parent.left.order + 1
- }
- x = x.parent
- }
-
- return r
- }
-
- /**
- :name: validateOrder
- :description: Validates the order statistic being within range of 1...n.
- */
- private func validateOrder(_ order: Int) {
- assert(order > startIndex || order <= endIndex, "[Algorithm Error: Order out of bounds.]")
- }
-
- public static func ==(lhs: RedBlackTree, rhs: RedBlackTree) -> Bool {
- return lhs.count == rhs.count && lhs.elementsEqual(rhs, by: { a, b -> Bool in
- return a.key == b.key
- })
- }
-
- public static func !=(lhs: RedBlackTree, rhs: RedBlackTree) -> Bool {
- return !(lhs == rhs)
- }
-
- public static func +(lhs: RedBlackTree, rhs: RedBlackTree) -> RedBlackTree {
- var t = RedBlackTree()
-
- for (k, v) in lhs {
- t.insert(value: v, for: k)
- }
-
- for (k, v) in rhs {
- t.insert(value: v, for: k)
- }
-
- return t
- }
-
- public static func +=(lhs: inout RedBlackTree, rhs: RedBlackTree) {
- for (k, v) in rhs {
- lhs.insert(value: v, for: k)
- }
- }
-
- public static func -(lhs: RedBlackTree, rhs: RedBlackTree) -> RedBlackTree {
- var t = rhs
-
- for (k, _) in rhs {
- t.removeValue(for: k)
- }
-
- return t
- }
-
- public static func -=(lhs: inout RedBlackTree, rhs: RedBlackTree) {
- for (k, _) in rhs {
- lhs.removeValue(for: k)
- }
- }
-}
+ y.parent.left = x
+ }
+
+ x.right = y
+ y.parent = x
+ x.order = y.order
+ y.order = y.left.order + y.right.order + 1
+ }
+
+ /**
+ :name: internalFindNodeForKey
+ :description: Finds a node with a given key value.
+ - returns: RedBlackNode
+ */
+ private func internalFindNodeForKey(_ key: Key) -> RedBlackNode {
+ var z = root
+ while z !== sentinel {
+ if key == z.key {
+ return z
+ }
+ z = key < z.key as Key ? z.left : z.right
+ }
+ return sentinel
+ }
+
+ /**
+ :name: internalSelect
+ :description: Internally searches for a node by the order statistic value.
+ - returns: RedBlackNode
+ */
+ private func internalSelect(_ x: RedBlackNode, order: Int) -> RedBlackNode {
+ validateOrder(order)
+
+ let r = x.left.order + 1
+
+ if order == r {
+ return x
+ } else if order < r {
+ return internalSelect(x.left, order: order)
+ }
+
+ return internalSelect(x.right, order: order - r)
+ }
+
+ /**
+ :name: internalCount
+ :description: Traverses the Tree while counting number of times a key appears.
+ */
+ private func internalCount(_ key: Key, node: RedBlackNode, count: inout Int) {
+ if sentinel !== node {
+ if key == node.key {
+ count += 1
+ }
+
+ internalCount(key, node: node.left, count: &count)
+ internalCount(key, node: node.right, count: &count)
+ }
+ }
+
+ /**
+ :name: internalUpdateValue
+ :description: Traverses the Tree and updates all the values that match the key.
+ */
+ private func internalUpdateValue(_ value: Value?, for key: Key, node: RedBlackNode) {
+ if node !== sentinel {
+ if key == node.key {
+ node.value = value
+ }
+
+ internalUpdateValue(value, for: key, node: node.left)
+ internalUpdateValue(value, for: key, node: node.right)
+ }
+ }
+
+ /**
+ :name: internalOrder
+ :description: Traverses the Tree for the internal order statistic of a key.
+ - returns: Int
+ */
+ private func internalOrder(_ node: RedBlackNode) -> Int {
+ var x = node
+ var r: Int = x.left.order + 1
+
+ while root !== x {
+ if x.parent.right === x {
+ r += x.parent.left.order + 1
+ }
+ x = x.parent
+ }
+ return r
+ }
+
+ /**
+ :name: validateOrder
+ :description: Validates the order statistic being within range of 1...n.
+ */
+ private func validateOrder(_ order: Int) {
+ assert(order > startIndex || order <= endIndex, "[Algorithm Error: Order out of bounds.]")
+ }
+
+ public static func == (lhs: RedBlackTree, rhs: RedBlackTree) -> Bool {
+ return lhs.count == rhs.count && lhs.elementsEqual(rhs, by: { a, b -> Bool in
+ a.key == b.key
+ })
+ }
+
+ public static func != (lhs: RedBlackTree, rhs: RedBlackTree) -> Bool {
+ return !(lhs == rhs)
+ }
+ public static func + (lhs: RedBlackTree, rhs: RedBlackTree) -> RedBlackTree {
+ var t = RedBlackTree()
+
+ for (k, v) in lhs {
+ t.insert(value: v, for: k)
+ }
+
+ for (k, v) in rhs {
+ t.insert(value: v, for: k)
+ }
+
+ return t
+ }
+
+ public static func += (lhs: inout RedBlackTree, rhs: RedBlackTree) {
+ for (k, v) in rhs {
+ lhs.insert(value: v, for: k)
+ }
+ }
+
+ public static func - (_: RedBlackTree, rhs: RedBlackTree) -> RedBlackTree {
+ var t = rhs
+
+ for (k, _) in rhs {
+ t.removeValue(for: k)
+ }
+
+ return t
+ }
+
+ public static func -= (lhs: inout RedBlackTree, rhs: RedBlackTree) {
+ for (k, _) in rhs {
+ lhs.removeValue(for: k)
+ }
+ }
+}
diff --git a/Sources/SortedDictionary.swift b/Sources/SortedDictionary.swift
index a7e86f3..05c318f 100644
--- a/Sources/SortedDictionary.swift
+++ b/Sources/SortedDictionary.swift
@@ -24,363 +24,362 @@
*/
public struct SortedDictionary: Probable, Collection, BidirectionalCollection, Equatable, CustomStringConvertible {
- public typealias Element = RedBlackTree.Element
- public typealias ProbableElement = RedBlackTree.ProbableElement
-
- /// Returns the position immediately after the given index.
- ///
- /// - Parameter i: A valid index of the collection. `i` must be less than
- /// `endIndex`.
- /// - Returns: The index value immediately after `i`.
- public func index(after i: Int) -> Int {
- return i + 1
- }
-
- public func index(before i: Int) -> Int {
- return i - 1
- }
-
- public typealias Iterator = AnyIterator
-
- /// Total number of elements within the RedBlackTree
- public internal(set) var count = 0
-
- /// Internal storage of (key, value) pairs.
- internal var tree: RedBlackTree
-
- /// Get the data as a Dictionary.
- public var asDictionary: [Key: Value?] {
- var d = [Key: Value?]()
- for (k, v) in self {
- d[k] = v
- }
- return d
- }
-
- /// Conforms to the Printable Protocol. Outputs the
- public var description: String {
- return tree.description
- }
-
- /// Conforms to the Collection Protocol.
- public var startIndex: Int {
- return 0
- }
-
- /// Conforms to the Collection Protocol.
- public var endIndex: Int {
- return count
- }
-
- /// Retrieves an Array of the key values in order.
- public var keys: [Key] {
- return tree.keys
- }
-
- /// Retrieves an Array of the values that are sorted based
- public var values: [Value] {
- return tree.values
- }
-
- /// Initializer.
- public init() {
- tree = RedBlackTree(uniqueKeys: true)
- }
-
- /**
- Initializes with a given list of elements.
- - Parameter elements: A list of (key, value) pairs.
- */
- public init(elements: (Key, Value?)...) {
- self.init(elements: elements)
- }
-
- /**
- Initializes with a given Array of elements.
- - Parameter elements: An Array of (key, value) pairs.
- */
- public init(elements: [(Key, Value?)]) {
- self.init()
- insert(elements)
- }
-
- fileprivate init(tree : RedBlackTree) {
- self.init()
- self.tree = tree
- }
-
- public func _customIndexOfEquatableElement(_ element: Key) -> Int?? {
- return nil
- }
-
- public func makeIterator() -> Iterator {
- var i = indices.makeIterator()
- return AnyIterator { i.next().map { self[$0] } }
- }
-
- /**
- Retrieves the total count of instances for the given
- keys.
- - Parameter of keys: A list of Key types.
- - Returns: An Int.
- */
- public func count(of keys: Key...) -> Int {
- return count(of: keys)
- }
-
- /**
- Retrieves the total count of instances for the given
- keys.
- - Parameter of keys: An Array of Key types.
- - Returns: An Int.
- */
- public func count(of keys: [Key]) -> Int {
- return tree.count(of: keys)
- }
-
- /**
- Calculates the probability of the given keys.
- - Parameter of keys: A list of Key types.
- - Returns: A Double.
- */
- public func probability(of keys: Key...) -> Double {
- return probability(of: keys)
- }
-
- /**
- Calculates the probability of the given keys.
- - Parameter of keys: An Array of Key types.
- - Returns: A Double.
- */
- public func probability(of keys: [Key]) -> Double {
- return tree.probability(of: keys)
- }
-
- /**
- Calculates the probability using a block.
- - Parameter execute block: A block function to execute.
- - Returns: A Double.
- */
- public func probability(execute block: (Key, Value?) -> Bool) -> Double {
- return tree.probability(execute: block)
- }
-
- /**
- The expected value of given keys based on a number of trials.
- - Parameter trials: An Int.
- - Parameter for keys: A list of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for keys: Key...) -> Double {
- return expectedValue(trials: trials, for: keys)
- }
-
- /**
- The expected value of given keys based on a number of trials.
- - Parameter trials: An Int.
- - Parameter for keys: A list of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for keys: [Key]) -> Double {
- return tree.expectedValue(trials: trials, for: keys)
- }
-
- /**
- Property key mapping. If the key type is a String, this feature
- allows access like a Dictionary.
- - Parameter key: A Key type.
- - Returns: An optional Value type.
- */
- public subscript(key: Key) -> Value? {
- get {
- return tree[key]
- }
- set(value) {
- tree[key] = value
- count = tree.count
- }
- }
-
- public subscript(position: Int) -> Key {
- return self[position].key
- }
-
- /**
- Allows Array like access of the index. Items are kept in order,
- so when iterating through the items, they are returned in their
- ordered form.
- - Parameter index: An Int.
- - Returns: A (key: Key, value: Value?)
- */
- public subscript(index: Int) -> (key: Key, value: Value?) {
- get {
- return tree[index]
- }
- set(value) {
- tree[index] = value
- count = tree.count
- }
- }
-
- /**
- Returns the Index of a given member, or -1 if the member is not
- present.
- - Parameter of key: A Key type.
- - Returns: An Int.
- */
- public func index(of key: Key) -> Int {
- return tree.index(of: key)
- }
-
- /**
- Insert a key / value pair.
- - Parameter value: An optional Value type.
- - Parameter for key: A Key type.
- - Returns: A boolean of the result, true if inserted, false
- otherwise.
- */
- @discardableResult
- mutating public func insert(value: Value?, for key: Key) -> Bool {
- let result = tree.insert(value: value, for: key)
- count = tree.count
- return result
- }
-
- /**
- Inserts a list of key / value pairs.
- - Parameter elements: A list of (Key, Value?) tuples.
- */
- mutating public func insert(_ elements: (Key, Value?)...) {
- insert(elements)
- }
-
- /**
- Inserts an Array of key / value pairs.
- - Parameter elements: An Array of (Key, Value?) tuples.
- */
- mutating public func insert(_ elements: [(Key, Value?)]) {
- tree.insert(elements)
- count = tree.count
- }
-
- /**
- Removes key / value pairs based on the keys given.
- - Parameter for keys: A list of Key types.
- */
- mutating public func removeValue(for keys: Key...) {
- removeValue(for: keys)
- }
-
- /**
- Removes key / value pairs based on the keys given.
- - Parameter for keys: An Array of Key types.
- */
- mutating public func removeValue(for keys: [Key]) {
- tree.removeValue(for: keys)
- count = tree.count
- }
-
- /// Removes all key / value pairs.
- mutating public func removeAll() {
- tree.removeAll()
- count = tree.count
- }
-
- /**
- Updates a vlue for the given key.
- - Parameter value: An optional Value type.
- - Parameter for key: A Key type.
- */
- mutating public func update(value: Value?, for key: Key) {
- tree.update(value: value, for: key)
- }
-
- /**
- Finds the value for a given key.
- - Parameter for key: A Key type.
- - Returns: An optional Value type.
- */
- public func findValue(for key: Key) -> Value? {
- return tree.findValue(for: key)
- }
-
- /**
- Finds the value for a key which is less or equal given.
- - Parameter for key: A Key type.
- - Returns: An optional Value type.
- */
- public func findLowerEntry(for key: Key) -> Value? {
- return tree.findLowerValue(for: key)
- }
-
- /**
- Finds the value for a key which is larger or equal given.
- - Parameter for key: A Key type.
- - Returns: An optional Value type.
- */
- public func findCeilingEntry(for key: Key) -> Value? {
- return tree.findCeilingValue(for: key)
- }
-
- /**
- Searches for given keys in the SortedDictionary.
- - Parameter for keys: A list of Key types.
- - Returns: A SortedDictionary.
- */
- public func search(for keys: Key...) -> SortedDictionary {
- return search(for: keys)
- }
-
- /**
- Searches for given keys in the SortedDictionary.
- - Parameter for keys: An Array of Key types.
- - Returns: A SortedDictionary.
- */
- public func search(for keys: [Key]) -> SortedDictionary {
- var d = SortedDictionary()
- for key in keys {
- traverse(for: key, node: tree.root, dictionary: &d)
- }
- return d
- }
-
- /**
- Traverses the SortedDictionary, looking for a key matches.
- - Parameter for key: A Key type.
- - Parameter node: A RedBlackNode.
- - Parameter dictionary: A SortedDictionary to map the results too.
- */
- internal func traverse(for key: Key, node: RedBlackNode, dictionary: inout SortedDictionary) {
- guard tree.sentinel !== node else {
- return
- }
-
- if key == node.key {
- dictionary.insert(value: node.value, for: key)
- }
-
- traverse(for: key, node: node.left, dictionary: &dictionary)
- traverse(for: key, node: node.right, dictionary: &dictionary)
- }
-
- static public func ==(lhs: SortedDictionary, rhs: SortedDictionary) -> Bool {
- return lhs.tree == rhs.tree
- }
-
- static public func +(lhs: SortedDictionary, rhs: SortedDictionary) -> SortedDictionary {
- return SortedDictionary(tree : lhs.tree + rhs.tree)
- }
-
- static public func +=(lhs: inout SortedDictionary, rhs: SortedDictionary) {
- lhs.tree += rhs.tree
- }
-
- static public func -(lhs: SortedDictionary, rhs: SortedDictionary) -> SortedDictionary {
- return SortedDictionary(tree : lhs.tree - rhs.tree)
- }
-
- static public func -=(lhs: inout SortedDictionary, rhs: SortedDictionary) {
- lhs.tree -= rhs.tree
- }
-}
+ public typealias Element = RedBlackTree.Element
+ public typealias ProbableElement = RedBlackTree.ProbableElement
+
+ /// Returns the position immediately after the given index.
+ ///
+ /// - Parameter i: A valid index of the collection. `i` must be less than
+ /// `endIndex`.
+ /// - Returns: The index value immediately after `i`.
+ public func index(after i: Int) -> Int {
+ return i + 1
+ }
+
+ public func index(before i: Int) -> Int {
+ return i - 1
+ }
+
+ public typealias Iterator = AnyIterator
+
+ /// Total number of elements within the RedBlackTree
+ public internal(set) var count = 0
+
+ /// Internal storage of (key, value) pairs.
+ internal var tree: RedBlackTree
+
+ /// Get the data as a Dictionary.
+ public var asDictionary: [Key: Value?] {
+ var d = [Key: Value?]()
+ for (k, v) in self {
+ d[k] = v
+ }
+ return d
+ }
+
+ /// Conforms to the Printable Protocol. Outputs the
+ public var description: String {
+ return tree.description
+ }
+
+ /// Conforms to the Collection Protocol.
+ public var startIndex: Int {
+ return 0
+ }
+
+ /// Conforms to the Collection Protocol.
+ public var endIndex: Int {
+ return count
+ }
+
+ /// Retrieves an Array of the key values in order.
+ public var keys: [Key] {
+ return tree.keys
+ }
+
+ /// Retrieves an Array of the values that are sorted based
+ public var values: [Value] {
+ return tree.values
+ }
+
+ /// Initializer.
+ public init() {
+ tree = RedBlackTree(uniqueKeys: true)
+ }
+
+ /**
+ Initializes with a given list of elements.
+ - Parameter elements: A list of (key, value) pairs.
+ */
+ public init(elements: (Key, Value?)...) {
+ self.init(elements: elements)
+ }
+
+ /**
+ Initializes with a given Array of elements.
+ - Parameter elements: An Array of (key, value) pairs.
+ */
+ public init(elements: [(Key, Value?)]) {
+ self.init()
+ insert(elements)
+ }
+
+ fileprivate init(tree: RedBlackTree) {
+ self.init()
+ self.tree = tree
+ }
+
+ public func _customIndexOfEquatableElement(_: Key) -> Int?? {
+ return nil
+ }
+
+ public func makeIterator() -> Iterator {
+ var i = indices.makeIterator()
+ return AnyIterator { i.next().map { self[$0] } }
+ }
+
+ /**
+ Retrieves the total count of instances for the given
+ keys.
+ - Parameter of keys: A list of Key types.
+ - Returns: An Int.
+ */
+ public func count(of keys: Key...) -> Int {
+ return count(of: keys)
+ }
+
+ /**
+ Retrieves the total count of instances for the given
+ keys.
+ - Parameter of keys: An Array of Key types.
+ - Returns: An Int.
+ */
+ public func count(of keys: [Key]) -> Int {
+ return tree.count(of: keys)
+ }
+
+ /**
+ Calculates the probability of the given keys.
+ - Parameter of keys: A list of Key types.
+ - Returns: A Double.
+ */
+ public func probability(of keys: Key...) -> Double {
+ return probability(of: keys)
+ }
+
+ /**
+ Calculates the probability of the given keys.
+ - Parameter of keys: An Array of Key types.
+ - Returns: A Double.
+ */
+ public func probability(of keys: [Key]) -> Double {
+ return tree.probability(of: keys)
+ }
+
+ /**
+ Calculates the probability using a block.
+ - Parameter execute block: A block function to execute.
+ - Returns: A Double.
+ */
+ public func probability(execute block: (Key, Value?) -> Bool) -> Double {
+ return tree.probability(execute: block)
+ }
+
+ /**
+ The expected value of given keys based on a number of trials.
+ - Parameter trials: An Int.
+ - Parameter for keys: A list of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for keys: Key...) -> Double {
+ return expectedValue(trials: trials, for: keys)
+ }
+
+ /**
+ The expected value of given keys based on a number of trials.
+ - Parameter trials: An Int.
+ - Parameter for keys: A list of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for keys: [Key]) -> Double {
+ return tree.expectedValue(trials: trials, for: keys)
+ }
+ /**
+ Property key mapping. If the key type is a String, this feature
+ allows access like a Dictionary.
+ - Parameter key: A Key type.
+ - Returns: An optional Value type.
+ */
+ public subscript(key: Key) -> Value? {
+ get {
+ return tree[key]
+ }
+ set(value) {
+ tree[key] = value
+ count = tree.count
+ }
+ }
+
+ public subscript(position: Int) -> Key {
+ return self[position].key
+ }
+
+ /**
+ Allows Array like access of the index. Items are kept in order,
+ so when iterating through the items, they are returned in their
+ ordered form.
+ - Parameter index: An Int.
+ - Returns: A (key: Key, value: Value?)
+ */
+ public subscript(index: Int) -> (key: Key, value: Value?) {
+ get {
+ return tree[index]
+ }
+ set(value) {
+ tree[index] = value
+ count = tree.count
+ }
+ }
+
+ /**
+ Returns the Index of a given member, or -1 if the member is not
+ present.
+ - Parameter of key: A Key type.
+ - Returns: An Int.
+ */
+ public func index(of key: Key) -> Int {
+ return tree.index(of: key)
+ }
+
+ /**
+ Insert a key / value pair.
+ - Parameter value: An optional Value type.
+ - Parameter for key: A Key type.
+ - Returns: A boolean of the result, true if inserted, false
+ otherwise.
+ */
+ @discardableResult
+ public mutating func insert(value: Value?, for key: Key) -> Bool {
+ let result = tree.insert(value: value, for: key)
+ count = tree.count
+ return result
+ }
+
+ /**
+ Inserts a list of key / value pairs.
+ - Parameter elements: A list of (Key, Value?) tuples.
+ */
+ public mutating func insert(_ elements: (Key, Value?)...) {
+ insert(elements)
+ }
+
+ /**
+ Inserts an Array of key / value pairs.
+ - Parameter elements: An Array of (Key, Value?) tuples.
+ */
+ public mutating func insert(_ elements: [(Key, Value?)]) {
+ tree.insert(elements)
+ count = tree.count
+ }
+
+ /**
+ Removes key / value pairs based on the keys given.
+ - Parameter for keys: A list of Key types.
+ */
+ public mutating func removeValue(for keys: Key...) {
+ removeValue(for: keys)
+ }
+
+ /**
+ Removes key / value pairs based on the keys given.
+ - Parameter for keys: An Array of Key types.
+ */
+ public mutating func removeValue(for keys: [Key]) {
+ tree.removeValue(for: keys)
+ count = tree.count
+ }
+
+ /// Removes all key / value pairs.
+ public mutating func removeAll() {
+ tree.removeAll()
+ count = tree.count
+ }
+
+ /**
+ Updates a vlue for the given key.
+ - Parameter value: An optional Value type.
+ - Parameter for key: A Key type.
+ */
+ public mutating func update(value: Value?, for key: Key) {
+ tree.update(value: value, for: key)
+ }
+
+ /**
+ Finds the value for a given key.
+ - Parameter for key: A Key type.
+ - Returns: An optional Value type.
+ */
+ public func findValue(for key: Key) -> Value? {
+ return tree.findValue(for: key)
+ }
+
+ /**
+ Finds the value for a key which is less or equal given.
+ - Parameter for key: A Key type.
+ - Returns: An optional Value type.
+ */
+ public func findLowerEntry(for key: Key) -> Value? {
+ return tree.findLowerValue(for: key)
+ }
+
+ /**
+ Finds the value for a key which is larger or equal given.
+ - Parameter for key: A Key type.
+ - Returns: An optional Value type.
+ */
+ public func findCeilingEntry(for key: Key) -> Value? {
+ return tree.findCeilingValue(for: key)
+ }
+
+ /**
+ Searches for given keys in the SortedDictionary.
+ - Parameter for keys: A list of Key types.
+ - Returns: A SortedDictionary.
+ */
+ public func search(for keys: Key...) -> SortedDictionary {
+ return search(for: keys)
+ }
+
+ /**
+ Searches for given keys in the SortedDictionary.
+ - Parameter for keys: An Array of Key types.
+ - Returns: A SortedDictionary.
+ */
+ public func search(for keys: [Key]) -> SortedDictionary {
+ var d = SortedDictionary()
+ for key in keys {
+ traverse(for: key, node: tree.root, dictionary: &d)
+ }
+ return d
+ }
+
+ /**
+ Traverses the SortedDictionary, looking for a key matches.
+ - Parameter for key: A Key type.
+ - Parameter node: A RedBlackNode.
+ - Parameter dictionary: A SortedDictionary to map the results too.
+ */
+ internal func traverse(for key: Key, node: RedBlackNode, dictionary: inout SortedDictionary) {
+ guard tree.sentinel !== node else {
+ return
+ }
+
+ if key == node.key {
+ dictionary.insert(value: node.value, for: key)
+ }
+
+ traverse(for: key, node: node.left, dictionary: &dictionary)
+ traverse(for: key, node: node.right, dictionary: &dictionary)
+ }
+
+ public static func == (lhs: SortedDictionary, rhs: SortedDictionary) -> Bool {
+ return lhs.tree == rhs.tree
+ }
+
+ public static func + (lhs: SortedDictionary, rhs: SortedDictionary) -> SortedDictionary {
+ return SortedDictionary(tree: lhs.tree + rhs.tree)
+ }
+
+ public static func += (lhs: inout SortedDictionary, rhs: SortedDictionary) {
+ lhs.tree += rhs.tree
+ }
+
+ public static func - (lhs: SortedDictionary, rhs: SortedDictionary) -> SortedDictionary {
+ return SortedDictionary(tree: lhs.tree - rhs.tree)
+ }
+
+ public static func -= (lhs: inout SortedDictionary, rhs: SortedDictionary) {
+ lhs.tree -= rhs.tree
+ }
+}
diff --git a/Sources/SortedMultiDictionary.swift b/Sources/SortedMultiDictionary.swift
index b2ccc4c..9f3ff47 100644
--- a/Sources/SortedMultiDictionary.swift
+++ b/Sources/SortedMultiDictionary.swift
@@ -24,379 +24,379 @@
*/
public struct SortedMultiDictionary: Probable, Collection, Equatable, CustomStringConvertible where Key: Hashable {
- public typealias Element = RedBlackTree.Element
-
- /// Returns the position immediately after the given index.
- ///
- /// - Parameter i: A valid index of the collection. `i` must be less than
- /// `endIndex`.
- /// - Returns: The index value immediately after `i`.
- public func index(after i: Int) -> Int {
- return i < endIndex ? i + 1 : 0
- }
-
- public typealias Iterator = AnyIterator<(key: Key, value: Value?)>
-
- /// Total number of elements within the RedBlackTree
- public internal(set) var count = 0
-
- /// Internal storage of (key, value) pairs.
- internal var tree: RedBlackTree
-
- /// Get the data as a Dictionary.
- public var asDictionary: [Key: Value?] {
- var d = [Key: Value?]()
-
- for (k, v) in self {
- d[k] = v
- }
-
- return d
- }
-
- /// Conforms to the Printable Protocol. Outputs the
- public var description: String {
- return tree.description
- }
-
- /// Get the first (key, value) pair.
- public var first: (key: Key, value: Value?)? {
- return tree.first
- }
-
- /// Get the last (key, value) pair.
- public var last: (key: Key, value: Value?)? {
- return tree.last
- }
-
- /// A boolean of whether the SortedMultiDictionary is empty.
- public var isEmpty: Bool {
- return 0 == count
- }
-
- /// Conforms to the Collection Protocol.
- public var startIndex: Int {
- return 0
- }
-
- /// Conforms to the Collection Protocol.
- public var endIndex: Int {
- return count
- }
-
- /// Retrieves an Array of the key values in order.
- public var keys: [Key] {
- return tree.keys
- }
-
- /// Retrieves an Array of the values that are sorted based
- public var values: [Value] {
- return tree.values
- }
-
- /// Initializer.
- public init() {
- tree = RedBlackTree(uniqueKeys: false)
- }
-
- /**
- Initializes with a given list of elements.
- - Parameter elements: A list of (key, value) pairs.
- */
- public init(elements: (Key, Value?)...) {
- self.init(elements: elements)
- }
-
- /**
- Initializes with a given Array of elements.
- - Parameter elements: An Array of (key, value) pairs.
- */
- public init(elements: [(Key, Value?)]) {
- self.init()
- insert(elements)
- }
-
- public func _customIndexOfEquatableElement(_ element: Key) -> Int?? {
- return nil
- }
-
- public func makeIterator() -> SortedMultiDictionary.Iterator {
- var i = indices.makeIterator()
- return AnyIterator { i.next().map { self[$0] } }
- }
-
- /**
- Retrieves the total count of instances for the given
- keys.
- - Parameter of keys: A list of Key types.
- - Returns: An Int.
- */
- public func count(of keys: Key...) -> Int {
- return count(of: keys)
- }
-
- /**
- Retrieves the total count of instances for the given
- keys.
- - Parameter of keys: An Array of Key types.
- - Returns: An Int.
- */
- public func count(of keys: [Key]) -> Int {
- return tree.count(of: keys)
- }
-
- /**
- Calculates the probability of the given keys.
- - Parameter of keys: A list of Key types.
- - Returns: A Double.
- */
- public func probability(of keys: Key...) -> Double {
- return probability(of: keys)
- }
-
- /**
- Calculates the probability of the given keys.
- - Parameter of keys: An Array of Key types.
- - Returns: A Double.
- */
- public func probability(of keys: [Key]) -> Double {
- return tree.probability(of: keys)
- }
-
- /**
- Calculates the probability using a block.
- - Parameter execute block: A block function to execute.
- - Returns: A Double.
- */
- public func probability(execute block: (Key, Value?) -> Bool) -> Double {
- return tree.probability(execute: block)
- }
-
- /**
- The expected value of given keys based on a number of trials.
- - Parameter trials: An Int.
- - Parameter for keys: A list of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for keys: Key...) -> Double {
- return expectedValue(trials: trials, for: keys)
- }
-
- /**
- The expected value of given keys based on a number of trials.
- - Parameter trials: An Int.
- - Parameter for keys: A list of Elements.
- - Returns: A Double.
- */
- public func expectedValue(trials: Int, for keys: [Key]) -> Double {
- return tree.expectedValue(trials: trials, for: keys)
- }
-
- /**
- Property key mapping. If the key type is a String, this feature
- allows access like a Dictionary.
- - Parameter key: A Key type.
- - Returns: An optional Value type.
- */
- public subscript(key: Key) -> Value? {
- get {
- return tree[key]
- }
- set(value) {
- tree[key] = value
- count = tree.count
- }
- }
-
- /**
- Returns the Key value at a given position.
- - Parameter position: An Int.
- - Returns: A Key.
- */
- public subscript(position: Int) -> Key {
- return tree[position]
- }
-
- /**
- Allows Array like access of the index. Items are kept in order,
- so when iterating through the items, they are returned in their
- ordered form.
- - Parameter index: An Int.
- - Returns: A (key: Key, value: Value?)
- */
- public subscript(index: Int) -> (key: Key, value: Value?) {
- get {
- return tree[index]
- }
- set(value) {
- tree[index] = value
- count = tree.count
- }
- }
-
- /**
- Returns the Index of a given member, or -1 if the member is not
- present.
- - Parameter of key: A Key type.
- - Returns: An Int.
- */
- public func index(of key: Key) -> Int {
- return tree.index(of: key)
- }
-
- /**
- Insert a key / value pair.
- - Parameter value: An optional Value type.
- - Parameter for key: A Key type.
- - Returns: A boolean of the result, true if inserted, false
- otherwise.
- */
- @discardableResult
- mutating public func insert(value: Value?, for key: Key) -> Bool {
- let result = tree.insert(value: value, for: key)
- count = tree.count
- return result
- }
-
- /**
- Inserts a list of key / value pairs.
- - Parameter elements: A list of (Key, Value?) tuples.
- */
- mutating public func insert(_ elements: (Key, Value?)...) {
- insert(elements)
- }
-
- /**
- Inserts an Array of key / value pairs.
- - Parameter elements: An Array of (Key, Value?) tuples.
- */
- mutating public func insert(_ elements: [(Key, Value?)]) {
- tree.insert(elements)
- count = tree.count
- }
-
- /**
- Removes key / value pairs based on the keys given.
- - Parameter for keys: A list of Key types.
- */
- mutating public func removeValue(for keys: Key...) {
- removeValue(for: keys)
- }
-
- /**
- Removes key / value pairs based on the keys given.
- - Parameter for keys: An Array of Key types.
- */
- mutating public func removeValue(for keys: [Key]) {
- tree.removeValue(for: keys)
- count = tree.count
- }
-
- /// Removes all key / value pairs.
- mutating public func removeAll() {
- tree.removeAll()
- count = tree.count
- }
-
- /**
- Updates a vlue for the given key.
- - Parameter value: An optional Value type.
- - Parameter for key: A Key type.
- */
- mutating public func update(value: Value?, for key: Key) {
- tree.update(value: value, for: key)
- }
-
- /**
- Finds the value for a given key.
- - Parameter for key: A Key type.
- - Returns: An optional Value type.
- */
- public func findValue(for key: Key) -> Value? {
- return tree.findValue(for: key)
- }
-
- /**
- Searches for given keys in the SortedMultiDictionary.
- - Parameter for keys: A list of Key types.
- - Returns: A SortedMultiDictionary.
- */
- public func search(for keys: Key...) -> SortedMultiDictionary {
- return search(for: keys)
- }
-
- /**
- Searches for given keys in the SortedMultiDictionary.
- - Parameter for keys: An Array of Key types.
- - Returns: A SortedMultiDictionary.
- */
- public func search(for keys: [Key]) -> SortedMultiDictionary {
- var d = SortedMultiDictionary()
- for key in keys {
- traverse(for: key, node: tree.root, dictionary: &d)
- }
- return d
- }
-
- /**
- Traverses the SortedMultiDictionary, looking for a key matches.
- - Parameter for key: A Key type.
- - Parameter node: A RedBlackNode.
- - Parameter dictionary: A SortedMultiDictionary to map the results too.
- */
- internal func traverse(for key: Key, node: RedBlackNode, dictionary: inout SortedMultiDictionary) {
- guard tree.sentinel !== node else {
- return
- }
-
- if key == node.key {
- dictionary.insert(value: node.value, for: key)
- }
-
- traverse(for: key, node: node.left, dictionary: &dictionary)
- traverse(for: key, node: node.right, dictionary: &dictionary)
- }
+ public typealias Element = RedBlackTree.Element
+
+ /// Returns the position immediately after the given index.
+ ///
+ /// - Parameter i: A valid index of the collection. `i` must be less than
+ /// `endIndex`.
+ /// - Returns: The index value immediately after `i`.
+ public func index(after i: Int) -> Int {
+ return i < endIndex ? i + 1 : 0
+ }
+
+ public typealias Iterator = AnyIterator<(key: Key, value: Value?)>
+
+ /// Total number of elements within the RedBlackTree
+ public internal(set) var count = 0
+
+ /// Internal storage of (key, value) pairs.
+ internal var tree: RedBlackTree
+
+ /// Get the data as a Dictionary.
+ public var asDictionary: [Key: Value?] {
+ var d = [Key: Value?]()
+
+ for (k, v) in self {
+ d[k] = v
+ }
+
+ return d
+ }
+
+ /// Conforms to the Printable Protocol. Outputs the
+ public var description: String {
+ return tree.description
+ }
+
+ /// Get the first (key, value) pair.
+ public var first: (key: Key, value: Value?)? {
+ return tree.first
+ }
+
+ /// Get the last (key, value) pair.
+ public var last: (key: Key, value: Value?)? {
+ return tree.last
+ }
+
+ /// A boolean of whether the SortedMultiDictionary is empty.
+ public var isEmpty: Bool {
+ return count == 0
+ }
+
+ /// Conforms to the Collection Protocol.
+ public var startIndex: Int {
+ return 0
+ }
+
+ /// Conforms to the Collection Protocol.
+ public var endIndex: Int {
+ return count
+ }
+
+ /// Retrieves an Array of the key values in order.
+ public var keys: [Key] {
+ return tree.keys
+ }
+
+ /// Retrieves an Array of the values that are sorted based
+ public var values: [Value] {
+ return tree.values
+ }
+
+ /// Initializer.
+ public init() {
+ tree = RedBlackTree(uniqueKeys: false)
+ }
+
+ /**
+ Initializes with a given list of elements.
+ - Parameter elements: A list of (key, value) pairs.
+ */
+ public init(elements: (Key, Value?)...) {
+ self.init(elements: elements)
+ }
+
+ /**
+ Initializes with a given Array of elements.
+ - Parameter elements: An Array of (key, value) pairs.
+ */
+ public init(elements: [(Key, Value?)]) {
+ self.init()
+ insert(elements)
+ }
+
+ public func _customIndexOfEquatableElement(_: Key) -> Int?? {
+ return nil
+ }
+
+ public func makeIterator() -> SortedMultiDictionary.Iterator {
+ var i = indices.makeIterator()
+ return AnyIterator { i.next().map { self[$0] } }
+ }
+
+ /**
+ Retrieves the total count of instances for the given
+ keys.
+ - Parameter of keys: A list of Key types.
+ - Returns: An Int.
+ */
+ public func count(of keys: Key...) -> Int {
+ return count(of: keys)
+ }
+
+ /**
+ Retrieves the total count of instances for the given
+ keys.
+ - Parameter of keys: An Array of Key types.
+ - Returns: An Int.
+ */
+ public func count(of keys: [Key]) -> Int {
+ return tree.count(of: keys)
+ }
+
+ /**
+ Calculates the probability of the given keys.
+ - Parameter of keys: A list of Key types.
+ - Returns: A Double.
+ */
+ public func probability(of keys: Key...) -> Double {
+ return probability(of: keys)
+ }
+
+ /**
+ Calculates the probability of the given keys.
+ - Parameter of keys: An Array of Key types.
+ - Returns: A Double.
+ */
+ public func probability(of keys: [Key]) -> Double {
+ return tree.probability(of: keys)
+ }
+
+ /**
+ Calculates the probability using a block.
+ - Parameter execute block: A block function to execute.
+ - Returns: A Double.
+ */
+ public func probability(execute block: (Key, Value?) -> Bool) -> Double {
+ return tree.probability(execute: block)
+ }
+
+ /**
+ The expected value of given keys based on a number of trials.
+ - Parameter trials: An Int.
+ - Parameter for keys: A list of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for keys: Key...) -> Double {
+ return expectedValue(trials: trials, for: keys)
+ }
+
+ /**
+ The expected value of given keys based on a number of trials.
+ - Parameter trials: An Int.
+ - Parameter for keys: A list of Elements.
+ - Returns: A Double.
+ */
+ public func expectedValue(trials: Int, for keys: [Key]) -> Double {
+ return tree.expectedValue(trials: trials, for: keys)
+ }
+
+ /**
+ Property key mapping. If the key type is a String, this feature
+ allows access like a Dictionary.
+ - Parameter key: A Key type.
+ - Returns: An optional Value type.
+ */
+ public subscript(key: Key) -> Value? {
+ get {
+ return tree[key]
+ }
+ set(value) {
+ tree[key] = value
+ count = tree.count
+ }
+ }
+
+ /**
+ Returns the Key value at a given position.
+ - Parameter position: An Int.
+ - Returns: A Key.
+ */
+ public subscript(position: Int) -> Key {
+ return tree[position]
+ }
+
+ /**
+ Allows Array like access of the index. Items are kept in order,
+ so when iterating through the items, they are returned in their
+ ordered form.
+ - Parameter index: An Int.
+ - Returns: A (key: Key, value: Value?)
+ */
+ public subscript(index: Int) -> (key: Key, value: Value?) {
+ get {
+ return tree[index]
+ }
+ set(value) {
+ tree[index] = value
+ count = tree.count
+ }
+ }
+
+ /**
+ Returns the Index of a given member, or -1 if the member is not
+ present.
+ - Parameter of key: A Key type.
+ - Returns: An Int.
+ */
+ public func index(of key: Key) -> Int {
+ return tree.index(of: key)
+ }
+
+ /**
+ Insert a key / value pair.
+ - Parameter value: An optional Value type.
+ - Parameter for key: A Key type.
+ - Returns: A boolean of the result, true if inserted, false
+ otherwise.
+ */
+ @discardableResult
+ public mutating func insert(value: Value?, for key: Key) -> Bool {
+ let result = tree.insert(value: value, for: key)
+ count = tree.count
+ return result
+ }
+
+ /**
+ Inserts a list of key / value pairs.
+ - Parameter elements: A list of (Key, Value?) tuples.
+ */
+ public mutating func insert(_ elements: (Key, Value?)...) {
+ insert(elements)
+ }
+
+ /**
+ Inserts an Array of key / value pairs.
+ - Parameter elements: An Array of (Key, Value?) tuples.
+ */
+ public mutating func insert(_ elements: [(Key, Value?)]) {
+ tree.insert(elements)
+ count = tree.count
+ }
+
+ /**
+ Removes key / value pairs based on the keys given.
+ - Parameter for keys: A list of Key types.
+ */
+ public mutating func removeValue(for keys: Key...) {
+ removeValue(for: keys)
+ }
+
+ /**
+ Removes key / value pairs based on the keys given.
+ - Parameter for keys: An Array of Key types.
+ */
+ public mutating func removeValue(for keys: [Key]) {
+ tree.removeValue(for: keys)
+ count = tree.count
+ }
+
+ /// Removes all key / value pairs.
+ public mutating func removeAll() {
+ tree.removeAll()
+ count = tree.count
+ }
+
+ /**
+ Updates a vlue for the given key.
+ - Parameter value: An optional Value type.
+ - Parameter for key: A Key type.
+ */
+ public mutating func update(value: Value?, for key: Key) {
+ tree.update(value: value, for: key)
+ }
+
+ /**
+ Finds the value for a given key.
+ - Parameter for key: A Key type.
+ - Returns: An optional Value type.
+ */
+ public func findValue(for key: Key) -> Value? {
+ return tree.findValue(for: key)
+ }
+
+ /**
+ Searches for given keys in the SortedMultiDictionary.
+ - Parameter for keys: A list of Key types.
+ - Returns: A SortedMultiDictionary.
+ */
+ public func search(for keys: Key...) -> SortedMultiDictionary {
+ return search(for: keys)
+ }
+
+ /**
+ Searches for given keys in the SortedMultiDictionary.
+ - Parameter for keys: An Array of Key types.
+ - Returns: A SortedMultiDictionary.
+ */
+ public func search(for keys: [Key]) -> SortedMultiDictionary {
+ var d = SortedMultiDictionary()
+ for key in keys {
+ traverse(for: key, node: tree.root, dictionary: &d)
+ }
+ return d
+ }
+
+ /**
+ Traverses the SortedMultiDictionary, looking for a key matches.
+ - Parameter for key: A Key type.
+ - Parameter node: A RedBlackNode.
+ - Parameter dictionary: A SortedMultiDictionary to map the results too.
+ */
+ internal func traverse(for key: Key, node: RedBlackNode, dictionary: inout SortedMultiDictionary) {
+ guard tree.sentinel !== node else {
+ return
+ }
+
+ if key == node.key {
+ dictionary.insert(value: node.value, for: key)
+ }
+
+ traverse(for: key, node: node.left, dictionary: &dictionary)
+ traverse(for: key, node: node.right, dictionary: &dictionary)
+ }
}
-public func ==(lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> Bool {
- if lhs.count != rhs.count {
- return false
- }
- for i in 0..(lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> Bool {
+ if lhs.count != rhs.count {
+ return false
+ }
+ for i in 0 ..< lhs.count {
+ if lhs[i].key != rhs[i].key {
+ return false
+ }
}
- }
- return true
+ return true
}
-public func !=(lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> Bool {
- return !(lhs == rhs)
+public func != (lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> Bool {
+ return !(lhs == rhs)
}
-public func +(lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> SortedMultiDictionary {
- var t = SortedMultiDictionary()
- for (k, v) in lhs {
- t.insert(value: v, for: k)
- }
- for (k, v) in rhs {
- t.insert(value: v, for: k)
- }
- return t
+public func + (lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> SortedMultiDictionary {
+ var t = SortedMultiDictionary()
+ for (k, v) in lhs {
+ t.insert(value: v, for: k)
+ }
+ for (k, v) in rhs {
+ t.insert(value: v, for: k)
+ }
+ return t
}
-public func +=(lhs: inout SortedMultiDictionary, rhs: SortedMultiDictionary) {
- for (k, v) in rhs {
- lhs.insert(value: v, for: k)
- }
+public func += (lhs: inout SortedMultiDictionary, rhs: SortedMultiDictionary) {
+ for (k, v) in rhs {
+ lhs.insert(value: v, for: k)
+ }
}
-public func -(lhs: SortedMultiDictionary, rhs: SortedMultiDictionary