Skip to content

Commit 8008a24

Browse files
author
Robert Thompson
committed
Initial commit
1 parent 7711637 commit 8008a24

File tree

10 files changed

+1635
-0
lines changed

10 files changed

+1635
-0
lines changed

Treap/Treap.swift

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
//
2+
// Treap.swift
3+
// TreapExample
4+
//
5+
// Created by Robert Thompson on 7/27/15.
6+
// Copyright © 2015 Robert Thompson. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public indirect enum Treap<Key: Comparable, Element> {
12+
case Empty
13+
case Node(key: Key, val: Element, p: Int, left: Treap, right: Treap)
14+
15+
public init() {
16+
self = .Empty
17+
}
18+
19+
internal func get(key: Key) -> Element? {
20+
switch self {
21+
case .Empty:
22+
return nil
23+
case let .Node(treeKey, val, _, _, _) where treeKey == key:
24+
return val
25+
case let .Node(treeKey, _, _, left, _) where key < treeKey:
26+
return left.get(key)
27+
case let .Node(treeKey, _, _, _, right) where key > treeKey:
28+
return right.get(key)
29+
default:
30+
return nil
31+
}
32+
}
33+
34+
public func contains(key: Key) -> Bool {
35+
switch self {
36+
case .Empty:
37+
return false
38+
case let .Node(treeKey, _, _, _, _) where treeKey == key:
39+
return true
40+
case let .Node(treeKey, _, _, left, _) where key < treeKey:
41+
return left.contains(key)
42+
case let .Node(treeKey, _, _, _, right) where key > treeKey:
43+
return right.contains(key)
44+
default:
45+
return false
46+
}
47+
}
48+
49+
public var depth: Int {
50+
get {
51+
switch self {
52+
case .Empty:
53+
return 0
54+
case let .Node(_, _, _, left, .Empty):
55+
return 1 + left.depth
56+
case let .Node(_, _, _, .Empty, right):
57+
return 1 + right.depth
58+
case let .Node(_, _, _, left, right):
59+
let leftDepth = left.depth
60+
let rightDepth = right.depth
61+
return 1 + max(leftDepth, rightDepth)
62+
}
63+
64+
}
65+
}
66+
67+
public var count: Int {
68+
get {
69+
return Treap.countHelper(self)
70+
}
71+
}
72+
73+
private static func countHelper(treap: Treap<Key, Element>) -> Int
74+
{
75+
if case let .Node(_, _, _, left, right) = treap
76+
{
77+
return countHelper(left) + 1 + countHelper(right)
78+
}
79+
80+
return 0
81+
}
82+
}
83+
84+
internal func leftRotate<Key: Comparable, Element>(tree: Treap<Key, Element>) -> Treap<Key, Element> {
85+
if case let .Node(key, val, p, .Node(leftKey, leftVal, leftP, leftLeft, leftRight), right) = tree {
86+
return .Node(key: leftKey, val: leftVal, p: leftP, left: leftLeft, right: Treap.Node(key: key, val: val, p: p, left: leftRight, right: right))
87+
}
88+
else
89+
{
90+
return .Empty
91+
}
92+
}
93+
94+
internal func rightRotate<Key: Comparable, Element>(tree: Treap<Key, Element>) -> Treap<Key, Element> {
95+
if case let .Node(key, val, p, left, .Node(rightKey, rightVal, rightP, rightLeft, rightRight)) = tree {
96+
return .Node(key: rightKey, val: rightVal, p: rightP, left: Treap.Node(key: key, val: val, p: p, left: left, right: rightLeft), right: rightRight)
97+
}
98+
else
99+
{
100+
return .Empty
101+
}
102+
}
103+
104+
public extension Treap {
105+
internal func set(key: Key, val: Element, p: Int = Int(arc4random())) -> Treap {
106+
switch self {
107+
case .Empty:
108+
return .Node(key: key, val: val, p: p, left: .Empty, right: .Empty)
109+
case let .Node(nodeKey, nodeVal, nodeP, left, right) where key != nodeKey:
110+
return insertAndBalance(nodeKey, nodeVal, nodeP, left, right, key, val, p)
111+
case let .Node(nodeKey, _, nodeP, left, right) where key == nodeKey:
112+
return .Node(key: key, val: val, p: nodeP, left: left, right: right)
113+
default: // should never happen
114+
return .Empty
115+
}
116+
117+
}
118+
119+
private func insertAndBalance(nodeKey: Key, _ nodeVal: Element, _ nodeP: Int, _ left: Treap, _ right: Treap, _ key: Key, _ val: Element, _ p: Int) -> Treap {
120+
let newChild: Treap<Key, Element>
121+
let newNode: Treap<Key, Element>
122+
let rotate: (Treap) -> Treap
123+
if key < nodeKey {
124+
newChild = left.set(key, val: val, p: p)
125+
newNode = .Node(key: nodeKey, val: nodeVal, p: nodeP, left: newChild, right: right)
126+
rotate = leftRotate
127+
}
128+
else if key > nodeKey {
129+
newChild = right.set(key, val: val, p: p)
130+
newNode = .Node(key: nodeKey, val: nodeVal, p: nodeP, left: left, right: newChild)
131+
rotate = rightRotate
132+
}
133+
else {
134+
// It should be impossible to reach here
135+
newChild = .Empty
136+
newNode = .Empty
137+
return newNode
138+
}
139+
140+
if case let .Node(_, _, newChildP, _, _) = newChild where newChildP < nodeP {
141+
return rotate(newNode)
142+
}
143+
else {
144+
return newNode
145+
}
146+
}
147+
148+
internal func delete(key: Key) throws -> Treap {
149+
switch self {
150+
case .Empty:
151+
throw NSError(___domain: "com.wta.treap.errorDomain", code: -1, userInfo: nil)
152+
case let .Node(nodeKey, val, p, left, right) where key < nodeKey:
153+
return try Treap.Node(key: nodeKey, val: val, p: p, left: left.delete(key), right: right)
154+
case let .Node(nodeKey, val, p, left, right) where key > nodeKey:
155+
return try Treap.Node(key: nodeKey, val: val, p: p, left: left, right: right.delete(key))
156+
case let .Node(_, _, _, left, right):
157+
return merge(left, right: right)
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)