Skip to content

Commit c1f9713

Browse files
author
Chris Pilcher
committed
Merge pull request kodecocodes#45 from rothomp3/master
Treap using Indirect Enums
2 parents c6e6de5 + 3ed00a3 commit c1f9713

File tree

10 files changed

+1720
-0
lines changed

10 files changed

+1720
-0
lines changed

Treap/Treap.swift

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
//
2+
// Treap.swift
3+
// TreapExample
4+
//
5+
// Created by Robert Thompson on 7/27/15.
6+
// Copyright © 2016 Robert Thompson
7+
/* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.*/
24+
25+
import Foundation
26+
27+
public indirect enum Treap<Key: Comparable, Element> {
28+
case Empty
29+
case Node(key: Key, val: Element, p: Int, left: Treap, right: Treap)
30+
31+
public init() {
32+
self = .Empty
33+
}
34+
35+
internal func get(key: Key) -> Element? {
36+
switch self {
37+
case .Empty:
38+
return nil
39+
case let .Node(treeKey, val, _, _, _) where treeKey == key:
40+
return val
41+
case let .Node(treeKey, _, _, left, _) where key < treeKey:
42+
return left.get(key)
43+
case let .Node(treeKey, _, _, _, right) where key > treeKey:
44+
return right.get(key)
45+
default:
46+
return nil
47+
}
48+
}
49+
50+
public func contains(key: Key) -> Bool {
51+
switch self {
52+
case .Empty:
53+
return false
54+
case let .Node(treeKey, _, _, _, _) where treeKey == key:
55+
return true
56+
case let .Node(treeKey, _, _, left, _) where key < treeKey:
57+
return left.contains(key)
58+
case let .Node(treeKey, _, _, _, right) where key > treeKey:
59+
return right.contains(key)
60+
default:
61+
return false
62+
}
63+
}
64+
65+
public var depth: Int {
66+
get {
67+
switch self {
68+
case .Empty:
69+
return 0
70+
case let .Node(_, _, _, left, .Empty):
71+
return 1 + left.depth
72+
case let .Node(_, _, _, .Empty, right):
73+
return 1 + right.depth
74+
case let .Node(_, _, _, left, right):
75+
let leftDepth = left.depth
76+
let rightDepth = right.depth
77+
return 1 + max(leftDepth, rightDepth)
78+
}
79+
80+
}
81+
}
82+
83+
public var count: Int {
84+
get {
85+
return Treap.countHelper(self)
86+
}
87+
}
88+
89+
private static func countHelper(treap: Treap<Key, Element>) -> Int
90+
{
91+
if case let .Node(_, _, _, left, right) = treap
92+
{
93+
return countHelper(left) + 1 + countHelper(right)
94+
}
95+
96+
return 0
97+
}
98+
}
99+
100+
internal func leftRotate<Key: Comparable, Element>(tree: Treap<Key, Element>) -> Treap<Key, Element> {
101+
if case let .Node(key, val, p, .Node(leftKey, leftVal, leftP, leftLeft, leftRight), right) = tree {
102+
return .Node(key: leftKey, val: leftVal, p: leftP, left: leftLeft, right: Treap.Node(key: key, val: val, p: p, left: leftRight, right: right))
103+
}
104+
else
105+
{
106+
return .Empty
107+
}
108+
}
109+
110+
internal func rightRotate<Key: Comparable, Element>(tree: Treap<Key, Element>) -> Treap<Key, Element> {
111+
if case let .Node(key, val, p, left, .Node(rightKey, rightVal, rightP, rightLeft, rightRight)) = tree {
112+
return .Node(key: rightKey, val: rightVal, p: rightP, left: Treap.Node(key: key, val: val, p: p, left: left, right: rightLeft), right: rightRight)
113+
}
114+
else
115+
{
116+
return .Empty
117+
}
118+
}
119+
120+
public extension Treap {
121+
internal func set(key: Key, val: Element, p: Int = Int(arc4random())) -> Treap {
122+
switch self {
123+
case .Empty:
124+
return .Node(key: key, val: val, p: p, left: .Empty, right: .Empty)
125+
case let .Node(nodeKey, nodeVal, nodeP, left, right) where key != nodeKey:
126+
return insertAndBalance(nodeKey, nodeVal, nodeP, left, right, key, val, p)
127+
case let .Node(nodeKey, _, nodeP, left, right) where key == nodeKey:
128+
return .Node(key: key, val: val, p: nodeP, left: left, right: right)
129+
default: // should never happen
130+
return .Empty
131+
}
132+
133+
}
134+
135+
private func insertAndBalance(nodeKey: Key, _ nodeVal: Element, _ nodeP: Int, _ left: Treap, _ right: Treap, _ key: Key, _ val: Element, _ p: Int) -> Treap {
136+
let newChild: Treap<Key, Element>
137+
let newNode: Treap<Key, Element>
138+
let rotate: (Treap) -> Treap
139+
if key < nodeKey {
140+
newChild = left.set(key, val: val, p: p)
141+
newNode = .Node(key: nodeKey, val: nodeVal, p: nodeP, left: newChild, right: right)
142+
rotate = leftRotate
143+
}
144+
else if key > nodeKey {
145+
newChild = right.set(key, val: val, p: p)
146+
newNode = .Node(key: nodeKey, val: nodeVal, p: nodeP, left: left, right: newChild)
147+
rotate = rightRotate
148+
}
149+
else {
150+
// It should be impossible to reach here
151+
newChild = .Empty
152+
newNode = .Empty
153+
return newNode
154+
}
155+
156+
if case let .Node(_, _, newChildP, _, _) = newChild where newChildP < nodeP {
157+
return rotate(newNode)
158+
}
159+
else {
160+
return newNode
161+
}
162+
}
163+
164+
internal func delete(key: Key) throws -> Treap {
165+
switch self {
166+
case .Empty:
167+
throw NSError(___domain: "com.wta.treap.errorDomain", code: -1, userInfo: nil)
168+
case let .Node(nodeKey, val, p, left, right) where key < nodeKey:
169+
return try Treap.Node(key: nodeKey, val: val, p: p, left: left.delete(key), right: right)
170+
case let .Node(nodeKey, val, p, left, right) where key > nodeKey:
171+
return try Treap.Node(key: nodeKey, val: val, p: p, left: left, right: right.delete(key))
172+
case let .Node(_, _, _, left, right):
173+
return merge(left, right: right)
174+
}
175+
}
176+
}

0 commit comments

Comments
 (0)