forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbal_set_mini.ml
104 lines (90 loc) · 2.66 KB
/
bal_set_mini.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
type 'a t =
| Empty
| Node of 'a t * 'a * 'a t * int
let rec height = function
| Empty -> 0
| Node(_,_,_,h) -> h
let create l v r =
let hl = height l in
let hr = height r in
Node(l,v,r, if hl >= hr then hl + 1 else hr + 1)
let bal l v r =
let hl = height l in
let hr = height r in
if hl > hr + 2 then
match l with
| Empty -> Empty (* impossible *)
| Node(ll, lv, lr, _) ->
if height ll >= height lr then
create ll lv (create lr v r)
else
match lr with
| Empty -> Empty (* impossible *)
| Node(lrl, lrv, lrr, _)->
create (create ll lv lrl) lrv (create lrr v r)
else if hr > hl + 2 then
match r with
| Empty -> Empty (* impossible *)
| Node(rl, rv, rr, _) ->
if height rr >= height rl then
create (create l v rl) rv rr
else
match rl with
| Empty -> Empty (* impossible *)
| Node(rll, rlv, rlr, _) ->
create (create l v rll) rlv (create rlr rv rr)
else
Node(l, v, r, (if hl >= hr then hl + 1 else hr + 1))
let compare_int (x : int) y = if x > y then 1 else if x = y then 0 else -1
let rec add x = function
| Empty -> Node(Empty, x, Empty, 1)
| Node(l, v, r, _) as t ->
let c = compare_int x v in
if c = 0 then t else
if c < 0 then bal (add x l) v r else bal l v (add x r)
let rec min_elt def = function
| Empty -> def
| Node(Empty, v, r, _) -> v
| Node(l, v, r, _) -> min_elt v l
(*
let rec remove_min_elt tree = match tree with
| Empty -> Empty (* impossible *)
| Node(Empty, v, r, _) -> r
| Node(l, v, r, _) -> bal (remove_min_elt l) v r
*)
let rec remove_min_elt l v r =
match l with
| Empty -> r
| Node(ll,lv,lr,_) -> bal (remove_min_elt ll lv lr) v r
let internal_merge l r =
match (l, r) with
| (Empty, t) -> t
| (t, Empty) -> t
| (_, Node (rl,rv,rr,_) ) -> bal l (min_elt rv r) (remove_min_elt rl rv rr)
let rec remove x tree =
match tree with
| Empty -> Empty
| Node(l, v, r, _) ->
let c = compare_int x v in
if c = 0 then internal_merge l r else
if c < 0 then bal (remove x l) v r else bal l v (remove x r)
let rec mem x = function
| Empty -> false
| Node(l, v, r, _) ->
let c = compare_int x v in
c = 0 || mem x (if c < 0 then l else r)
let () =
let v = ref Empty in
let iter = 1_00_000 in
for i = 0 to iter do
v := add i !v
done;
for i = 0 to iter do
if not (mem i !v) then print_endline "impossible"
done;
for i = 0 to iter do
v := remove i !v
done;
match !v with
| Empty -> ()
| Node _ -> print_endline "impossible"