Advertisement
HPSmirnov

AVL Tree in OCaml

Jul 30th, 2020
1,989
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.61 KB | None | 0 0
  1. open Core;;
  2.  
  3. type 'a avl_tree =
  4.     | Empty
  5.     | Node of int * 'a * 'a avl_tree * 'a avl_tree;;
  6.  
  7. let avl_height = function
  8.     | Empty -> 0
  9.     | Node (h, _, _, _) -> h;;
  10.  
  11. let max_height l r =
  12.     Int.max (avl_height l) (avl_height r);;
  13.  
  14. let rotate_to_left tr =
  15.     match tr with
  16.     | Empty -> tr
  17.     | Node (_, x, t1, r) ->
  18.             match r with
  19.             | Empty -> tr
  20.             | Node(_, y, t2, t3) ->
  21.                     let tr = avl_height t3 in
  22.                     let tl = 1 + max_height t1 t2 in
  23.                     Node(1 + Int.max tr tl, y, Node(tl, x, t1, t2), t3);;
  24.  
  25. let rotate_to_right tr =
  26.     match tr with
  27.     | Empty -> tr
  28.     | Node(_, y, l, t3) ->
  29.             match l with
  30.             | Empty -> tr
  31.             | Node(_, x, t1, t2) ->
  32.                     let tl = avl_height t1 in
  33.                     let tr = 1 + max_height t2 t3 in
  34.                     Node (1 + Int.max tl tr, x, t1, Node(tr, y, t2, t3));;
  35.  
  36. let rec raw_insert tr w =
  37.     match tr with | Empty -> Node(1, w, Empty, Empty) | Node(_, v, l, r) as t->
  38.             if Int.(w < v) then
  39.                 let newl = raw_insert l w in
  40.                 Node (1 + max_height newl r, v, newl, r)
  41.             else if Int.(w > v) then
  42.                 let newr = raw_insert r w in
  43.                 Node(1 + max_height newr l, v, l, newr)
  44.             else t;;
  45.  
  46. type balance_state = Left | Right | Neutral
  47.  
  48. let check_balance l r =
  49.     let balance = (avl_height l) - (avl_height r) in
  50.     if Int.(balance < -1) then Right
  51.     else if Int.(balance > 1) then Left
  52.     else Neutral;;
  53.  
  54. let insert tree w =
  55.     let tr = raw_insert tree w in
  56.     match tr with
  57.     | Empty -> tr
  58.     | Node(h, v, l, r) ->
  59.             match check_balance l r with
  60.             | Neutral -> tr
  61.             | Right   ->
  62.                     (match r with
  63.                     | Empty -> tr
  64.                     | Node(rh, rv, t1, t2) ->
  65.                             if Int.(w < rv) then
  66.                                 rotate_to_left (Node(h, v, l, Node(rh, rv, rotate_to_right t1, t2)))
  67.                             else
  68.                                 rotate_to_left (Node(h, v, l, Node(rh, rv, t1, rotate_to_left t2))))
  69.             | Left ->
  70.                     (match l with
  71.                     | Empty -> tr
  72.                     | Node(lh, lv, t3, t4) ->
  73.                             if Int.(w < lv) then
  74.                                 rotate_to_right (Node(h, v, Node(lh, lv, rotate_to_right t3, t4), r))
  75.                             else
  76.                                 rotate_to_right (Node(h, v, Node(lh, lv, t3, rotate_to_left t4), r)));;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement