Advertisement
Guest User

Untitled

a guest
Nov 26th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. type t = Empty | Node of t * (int * int) * t * (int * int) * int
  2. (* typ t = Empty lub Node (lewe drzewo; przedzial (a, b) w danym wierzcholku; prawe_drzewo; (c, d), gdzie jezeli d = 0, c oznacza liczbę wierzcholkow, w innym przypadku c = max_int; wysokosc_drzewa) *)
  3. exception Impossible (* wyjatek opisujacy przypadki, ktore nigdy nie zostana wywolane *)
  4.  
  5. let empty = Empty
  6. let is_empty avl = avl = Empty
  7.  
  8. let numbers_of x =
  9.   match x with
  10.   | Empty -> (0, 0)
  11.   | Node (_, _, _, a, _) -> a
  12.  
  13. let height_of x =
  14.   match x with
  15.   | Empty -> 0
  16.   | Node (_, _, _, _, a) -> a
  17.  
  18. (* tworzymy drzewo ktorego lewy syn, prawy syn i wartosc w wierzcholku sa dane - jezeli liczba elementow <= 0 lub rowna max_int tzn, ze jest ich >= max_int *)
  19. let make_node l (a, b) r = Node (l, (a, b), r, (
  20.   let (ln, li) = numbers_of l in
  21.   let (rn, ri) = numbers_of r in
  22.     if b - a + 1 <= 0 || li > 0 || ri > 0 then (0, 1)
  23.     else if ln + rn + b - a + 1 <= 0 then (0, 1)
  24.     else if ln + rn + b - a + 1 = max_int then (0, 1)
  25.     else (ln + rn + b - a + 1, 0)),
  26.   (max (height_of l) (height_of r)) + 1)
  27.  
  28. let rec fold f avl acc =
  29.   match avl with
  30.   | Empty -> acc
  31.   | Node (l, (a, b), r, _, _) -> fold f r (f (a, b) (fold f l acc))
  32.  
  33. let rec iter f avl =
  34.   match avl with
  35.   | Empty -> ()
  36.   | Node (l, v, r, _, _) -> iter f l; f v; iter f r
  37.  
  38. (* operacja tworzenia drzewa - z maksymalnie jednym "balansowaniem" do wykonania *)
  39. let bal l k r =
  40.   let hl = height_of l in
  41.   let hr = height_of r in
  42.   if hl > hr + 2 then
  43.     match l with
  44.     | Node (ll, lk, lr, _, _) ->
  45.         if height_of ll >= height_of lr then make_node ll lk (make_node lr k r) else
  46.           (match lr with
  47.           | Node (lrl, lrk, lrr, _, _) ->
  48.               make_node (make_node ll lk lrl) lrk (make_node lrr k r)
  49.           | Empty -> assert false)
  50.     | Empty -> assert false
  51.   else if hr > hl + 2 then
  52.     match r with
  53.     | Node (rl, rk, rr, _, _) ->
  54.         if height_of rr >= height_of rl then make_node (make_node l k rl) rk rr else
  55.           (match rl with
  56.           | Node (rll, rlk, rlr, _, _) ->
  57.               make_node (make_node l k rll) rlk (make_node rlr rk rr)
  58.           | Empty -> assert false)
  59.     | Empty -> assert false
  60.   else make_node l k r
  61.  
  62. (* rozpatrujemy rozne przypadki nachodzenia na siebie przedzialow
  63. funkcja jest wykorzystywana tylko w add_one oraz w split_help dla (a, b) = (a, a),
  64. czyli dla split mozemy porownywac tylko b wzgledem (c, d),
  65. a dla add_one podobnie, bo zalozenie jest takie, ze przedzialy w add_one na siebie nie nachodza *)
  66. let cmp (a, b) (c, d) =
  67.   if b = c - 1 && c <> min_int then -3 else
  68.   if b < c then -2 else
  69.   if b = c then -1 else
  70.   if b > c && b < d then 0 else
  71.   if b = d then 1 else
  72.   if b = d + 1 && d <> max_int then 3 else
  73.   if b > d then 2 else 4
  74.  
  75. (* warunek poczatkowy - przedzial x ktory chcemy dodac do drzewa nie moze polaczyc sie z zadnym innym w drzewie,
  76. tzn nie ma przedzialow (a, x-1) oraz (x+1, b) (z uwzglednieniem min_int, max_int) lub nachodzacych na x *)
  77. let rec add_one x t =
  78. match t with
  79. | Node (l, k, r, _, _) ->
  80.     let c = cmp x k in
  81.     if c < 0 then bal (add_one x l) k r
  82.     else if c > 0 then bal l k (add_one x r)
  83.     else raise Impossible (* zalozenie add_one jest takie, ze przedzialy na siebie nie nachodza, zatem c nie bedzie rowne 0 dla wywolan cmp w add_one *)
  84. | Empty -> make_node Empty x Empty
  85.  
  86. (* laczymy 2 drzewa z ustalona srodkowa wartoscia; warunek poczatkowy - drzewa l i r sa poprawne oraz (a, b) jest
  87. wieksze niz dowolna wartosc z l i mniejsze niz dowolna wartosc z r *)
  88. let rec join l v r =
  89.   match (l, r) with
  90.   | Empty, _ -> add_one v r
  91.   | _, Empty -> add_one v l
  92.   | Node (ll, lv, lr, _, lh), Node (rl, rv, rr, _, rh) ->
  93.       if lh > rh + 2 then bal ll lv (join lr v r) else
  94.       if rh > lh + 2 then bal (join l v rl) rv rr else
  95.       make_node l v r
  96.  
  97. let rec min_elt t =
  98.   match t with
  99.   | Node (Empty, v, _, _, _) -> v
  100.   | Node (l, _, _, _, _) -> min_elt l
  101.   | Empty -> raise Impossible (* funkcja nigdy nie jest wywolywana dla s = Empty (patrz merge nizej) *)
  102.  
  103. let rec remove_min_elt t =
  104.   match t with
  105.   | Node (Empty, _, r, _, _) -> r
  106.   | Node (l, v, r, _, _) -> bal (remove_min_elt l) v r
  107.   | Empty -> raise Impossible (* funkcja nigdy nie jest wywolywana dla s = Empty (patrz merge nizej) *)
  108.  
  109. let merge t1 t2 =
  110.   match t1, t2 with
  111.   | Empty, _ -> t2
  112.   | _, Empty -> t1
  113.   | _ ->
  114.       let v = min_elt t2 in
  115.       join t1 v (remove_min_elt t2)
  116.  
  117. (* w zaleznosci od cmp (x, x) (a, b) dzielimy drzewo - funkcja zwraca (drzewo mniejszych wartosci, czy x znajduje sie w drzewie,
  118. drzewo wiekszych wartosci, ewentualny dodatek z lewej, ewentualny dodatek z prawej), gdzie "dodatki" to adnotacja, dokad rozszerzy
  119. sie przedzial, gdy laczy sie on z x *)
  120. let split_help x t =
  121.   let rec loop x t (ld, rd)=
  122.     match t with
  123.     | Empty -> (Empty, false, Empty, x, x)
  124.     | Node (l, (a, b), r, _, _) ->
  125.         let d = cmp (x, x) (a, b) in
  126.         if d = -2 then
  127.           let (nl, cc, nr, n_l, n_r) = loop x l (x, x)
  128.           in (nl, cc, join nr (a, b) r, min ld n_l, max rd n_r) else
  129.  
  130.         if d = 2 then
  131.           let (nl, cc, nr, n_l, n_r) = loop x r (x, x)
  132.           in (join l (a, b) nl , cc, nr, min ld n_l, max rd n_r) else
  133.  
  134.         if d = 0 then (l, true, r, a, b) else
  135.  
  136.         if d = -1 then (l, true, r, ld, b) else
  137.  
  138.         if d = 1 then (l, true, r, a, rd) else
  139.  
  140.         if d = -3 then
  141.           let (nl, cc, nr, n_l, n_r) = loop x l (x, x)
  142.           in (nl, false, merge nr r, min ld n_l, b) else
  143.  
  144.         if d = 3 then
  145.           let (nl, cc, nr, n_l, n_r) = loop x r (x, x)
  146.           in (merge l nl, false, nr, a, max rd n_r)
  147.  
  148.         else raise Impossible (* cmp rozpatruje wszystkie przypadki dla (x, x) (a, b), zatem nie bedzie innego przypadku niz liczby calkowite z przedzialu <-3, 3> *)
  149.   in loop x t (x, x)
  150.  
  151. let add (x, y) t =
  152.   let (s, _, _, a, _) = split_help x t in
  153.   let (_, _, g, _, b) = split_help y t in
  154.   join s (a, b) g
  155.  
  156. let remove (x, y) t =
  157.   let (s, _, _, a, _) = split_help x t in
  158.   let (_, _, g, _, b) = split_help y t in
  159.   let g = if x - a > 0 then add_one (a, x - 1) g else g in
  160.   let g = if b - y > 0 then add_one (y + 1, b) g else g in
  161.   merge s g
  162.  
  163. let split x t =
  164.   let (s, c, g, l_a, r_a) = split_help x t in
  165.   ((if l_a < x then (add_one (l_a, x - 1) s) else s),
  166.   c,
  167.   (if r_a > x then (add_one (x + 1, r_a) g) else g))
  168.  
  169. let elements x =
  170.   let rec loop acc x =
  171.     match x with
  172.     | Empty -> acc
  173.     | Node(l, k, r, _, _) -> loop (k :: (loop acc r)) l in
  174.     loop [] x
  175.  
  176. let rec mem x t =
  177.   match t with
  178.   | Empty -> false
  179.   | Node (l, (a, b), r, _, _) ->
  180.     if x >= a && x <= b then true
  181.     else if x < a then mem x l else mem x r
  182.  
  183. let rec below_help x t =
  184.   match t with
  185.   | Empty -> (0, 0)
  186.   | Node (l, (a, b), r, _, _) ->
  187.     let (ln, li) = numbers_of l in
  188.     if x > b then
  189.       let (b_n, b_i) = below_help x r in
  190.       if b_i > 0 || li > 0 then (max_int, 1)
  191.       else if b_n + ln + b - a + 1 <= 0 then (max_int, 1)
  192.       else (b_n + ln + b - a + 1, 0)
  193.     else if x >= a then
  194.       if li > 0 then (max_int, 1)
  195.       else if ln + x - a + 1 <= 0 then (max_int, 1)
  196.       else (ln + x - a + 1, 0)
  197.     else below_help x l
  198.  
  199. let below x t =
  200.   let (ans, _) = below_help x t in ans
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement