View difference between Paste ID: j0aV3DJQ and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | (* Treap.fsi *) |
2 | module Treap | |
3 | [<Sealed>] | |
4 | type Treap<'a> = | |
5 | member Contains : v:'a -> bool | |
6 | member Insert : v:'a -> Treap<'a> | |
7 | member Remove : v:'a -> Treap<'a> | |
8 | member Split : v:'a -> Treap<'a> * bool * Treap<'a> | |
9 | member Count : int | |
10 | member Max : 'a | |
11 | member Min : 'a | |
12 | ||
13 | val empty : ('a -> 'a -> int) -> Treap<'a> | |
14 | val toSeq : Treap<'a> -> seq<'a> | |
15 | val toSeqBack : Treap<'a> -> seq<'a> | |
16 | ||
17 | (* Treap.fs *) | |
18 | module Treap | |
19 | open System | |
20 | ||
21 | type 'a treap = | |
22 | | Nil of ('a -> 'a -> int) * Random | |
23 | | Node of ('a -> 'a -> int) * Random * int * 'a treap * 'a * 'a treap * int | |
24 | with | |
25 | member this.Comparer = | |
26 | match this with | |
27 | | Nil(comparer, rnd) -> comparer | |
28 | | Node(comparer, rnd, priority, left, x, right, count) -> comparer | |
29 | ||
30 | member this.Rnd = | |
31 | match this with | |
32 | | Nil(comparer, rnd) -> rnd | |
33 | | Node(comparer, rnd, priority, left, x, right, count) -> rnd | |
34 | ||
35 | member this.Priority = | |
36 | match this with | |
37 | | Nil(comparer, rnd) -> Int32.MinValue | |
38 | | Node(comparer, rnd, priority, left, x, right, count) -> priority | |
39 | ||
40 | member this.Left = | |
41 | match this with | |
42 | | Nil(comparer, rnd) -> failwith "Empty treap" | |
43 | | Node(comparer, rnd, priority, left, x, right, count) -> left | |
44 | ||
45 | member this.Right = | |
46 | match this with | |
47 | | Nil(comparer, rnd) -> failwith "Empty treap" | |
48 | | Node(comparer, rnd, priority, left, x, right, count) -> right | |
49 | ||
50 | member this.Value = | |
51 | match this with | |
52 | | Nil(comparer, rnd) -> failwith "Empty treap" | |
53 | | Node(comparer, rnd, priority, left, x, right, count) -> x | |
54 | ||
55 | member this.Count = | |
56 | match this with | |
57 | | Nil(comparer, rnd) -> 0 | |
58 | | Node(comparer, rnd, priority, left, x, right, count) -> count | |
59 | ||
60 | member this.Min = | |
61 | match this with | |
62 | | Nil(comparer, rnd) -> failwith "Empty treap" | |
63 | | Node(comparer, rnd, priority, Nil(comparer', rnd'), x, right, count) -> x | |
64 | | Node(comparer, rnd, priority, left, x, right, count) -> left.Min | |
65 | ||
66 | member this.Max = | |
67 | match this with | |
68 | | Nil(comparer, rnd) -> failwith "Empty treap" | |
69 | | Node(comparer, rnd, priority, left, x, Nil(comparer', rnd'), count) -> x | |
70 | | Node(comparer, rnd, priority, left, x, right, count) -> right.Max | |
71 | ||
72 | member this.IsEmpty = | |
73 | match this with | |
74 | | Nil(comparer, rnd) -> true | |
75 | | Node(comparer, rnd, priority, left, x, right, count) -> false | |
76 | ||
77 | ||
78 | ||
79 | let nil f = Nil(f, new Random()) | |
80 | let nextPriority (rnd : Random) = rnd.Next(Int32.MinValue, Int32.MaxValue) | |
81 | let makeWithPriority (l : 'a treap, v, r : 'a treap, priority) = Node(l.Comparer, l.Rnd, priority, l, v, r, l.Count + r.Count + 1) | |
82 | let make(l : 'a treap, v, r) = makeWithPriority(l, v, r, l.Rnd.Next(Int32.MinValue, Int32.MaxValue)) | |
83 | ||
84 | (* | |
85 | q Right Rotation p | |
86 | / \ --------------+ / \ | |
87 | p c a q | |
88 | / \ Left Rotation / \ | |
89 | a b +------------- b c | |
90 | *) | |
91 | ||
92 | let rotLeft = function | |
93 | | Node(pcomparer, prnd, ppriority, a, p, Node(qcomparer, qrnd, qpriority, b, q, c, qcount), pcount) -> | |
94 | makeWithPriority(makeWithPriority(a, p, b, ppriority), q, c, qpriority) | |
95 | | node -> node | |
96 | ||
97 | let rotRight = function | |
98 | | Node(qcomparer, qrnd, qpriority, Node(pcomparer, prnd, ppriority, a, p, b, pcount), q, c, qcount) -> | |
99 | makeWithPriority(a, p, makeWithPriority(b, q, c, qpriority), ppriority) | |
100 | | node -> node | |
101 | ||
102 | let balLeft = function | |
103 | | Node(comparer, rnd, priority, l, x, r, count) as node when priority < l.Priority -> rotRight node | |
104 | | node -> node | |
105 | ||
106 | let balRight = function | |
107 | | Node(comparer, rnd, priority, l, x, r, count) as node when priority < r.Priority -> rotLeft node | |
108 | | node -> node | |
109 | ||
110 | let rec contains v = function | |
111 | | Nil(comparer, rnd) -> false | |
112 | | Node(comparer, rnd, priority, left, x, right, count) -> | |
113 | let compare = comparer v x | |
114 | if compare < 0 then contains v left | |
115 | elif compare > 0 then contains v right | |
116 | else true | |
117 | ||
118 | let rec insert v = function | |
119 | | Nil(comparer, rnd) as node -> make(node, v, node) | |
120 | | Node(comparer, rnd, priority, left, x, right, count) as node -> | |
121 | let compare = comparer v x | |
122 | if compare < 0 then makeWithPriority(insert v left, x, right, priority) |> balLeft | |
123 | elif compare > 0 then makeWithPriority(left, x, insert v right, priority) |> balRight | |
124 | else node | |
125 | ||
126 | let rec remove v = function | |
127 | | Nil(comparer, rnd) as node -> node | |
128 | | Node(comparer, rnd, priority, left, x, right, count) as node -> | |
129 | let compare = comparer v x | |
130 | if compare < 0 then makeWithPriority(remove v left, x, right, priority) | |
131 | elif compare > 0 then makeWithPriority(left, x, remove v right, priority) | |
132 | else | |
133 | if not (left.IsEmpty) then | |
134 | let successor = left.Max | |
135 | let l' = remove successor left | |
136 | makeWithPriority(l', successor, right, priority) | |
137 | elif not (right.IsEmpty) then | |
138 | let successor = right.Min | |
139 | let r' = remove successor right | |
140 | makeWithPriority(left, successor, r', priority) | |
141 | else | |
142 | left // guaranteed to be nil | |
143 | ||
144 | let rec split v = function | |
145 | | Nil(comparer, rnd) as node -> node, false, node | |
146 | | Node(comparer, rnd, priority, left, x, right, count) as node -> | |
147 | let compare = comparer v x | |
148 | if compare < 0 then | |
149 | let left', found, r' = split v left | |
150 | let right' = makeWithPriority(r', x, right, priority) | |
151 | left', found, right' | |
152 | elif compare > 0 then | |
153 | let l', found, right' = split v right | |
154 | let left' = makeWithPriority(left, x, l', priority) | |
155 | left', found, right' | |
156 | else | |
157 | left, true, right | |
158 | ||
159 | (* | |
160 | // used for debugging in fsi | |
161 | ||
162 | let print t = | |
163 | let rec loop indent = function | |
164 | | Nil(comparer, rnd) -> () | |
165 | | Node(comparer, rnd, priority, left, x, right, count) -> | |
166 | let spaces = new String(' ', indent * 4) | |
167 | loop (indent + 1) right | |
168 | printfn "%s(%s, %i)" spaces (x.ToString()) priority | |
169 | loop (indent + 1) left | |
170 | loop 0 t | |
171 | ||
172 | let insert' v t = | |
173 | let t' = insert v t | |
174 | print t' | |
175 | t' | |
176 | ||
177 | let remove' v t = | |
178 | let t' = remove v t | |
179 | print t' | |
180 | t' | |
181 | ||
182 | *) | |
183 | ||
184 | [<Sealed>] | |
185 | type Treap<'a>(t : 'a treap) = | |
186 | member this.Internal = t | |
187 | member this.Insert v = Treap(insert v t) | |
188 | member this.Remove v = Treap(remove v t) | |
189 | member this.Split v = let l, found, r = split v t in Treap(l), found, Treap(r) | |
190 | member this.Contains v = contains v t | |
191 | member this.Count = t.Count | |
192 | member this.Min = t.Min | |
193 | member this.Max = t.Max | |
194 | ||
195 | let empty f = Treap(nil f) | |
196 | ||
197 | let toSeq (t : Treap<'a>) = | |
198 | let rec loop = function | |
199 | | Nil(comparer, rnd) -> Seq.empty | |
200 | | Node(comparer, rnd, priority, l, x, r, count) -> seq { yield! loop l; yield x; yield! loop r } | |
201 | loop t.Internal | |
202 | ||
203 | let toSeqBack (t : Treap<'a>) = | |
204 | let rec loop = function | |
205 | | Nil(comparer, rnd) -> Seq.empty | |
206 | | Node(comparer, rnd, priority, l, x, r, count) -> seq { yield! loop r; yield x; yield! loop l } | |
207 | loop t.Internal |