Advertisement
Guest User

Untitled

a guest
Feb 28th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.16 KB | None | 0 0
  1. type element = int;;
  2.  
  3. type color = Red | Black;;
  4.  
  5. type bicolor_tree = Empty |
  6. Cons of (color * element * bicolor_tree * bicolor_tree)
  7. ;;
  8.  
  9. let tree_empty = Empty;;
  10.  
  11. let tree1 =
  12. Cons (Black, 15,
  13. Cons (Black, 10,
  14. Empty,
  15. Empty
  16. ),
  17. Cons (Red, 22,
  18. Cons (Black, 17,
  19. Empty,
  20. Empty
  21. ),
  22. Cons (Black, 253,
  23. Empty,
  24. Cons (Red, 254,
  25. Empty,
  26. Empty
  27. )
  28. )
  29. )
  30. )
  31. ;;
  32.  
  33. let tree2 =
  34. Cons (Black, 17,
  35. Cons (Black, 15,
  36. Cons(Black, 10,
  37. Empty,
  38. Empty
  39. ),
  40. Cons(Black, 16,
  41. Empty,
  42. Empty
  43. )
  44. ),
  45. Cons (Black, 253,
  46. Cons (Black, 22,
  47. Empty,
  48. Empty
  49. ),
  50. Cons (Black, 254,
  51. Empty,
  52. Empty
  53. )
  54. )
  55. )
  56. ;;
  57.  
  58. (* Ex 1 *)
  59.  
  60.  
  61.  
  62. (* Exercice précédent *)
  63.  
  64. (*Preuve : Fonction prenant un arbre en paramètre et transforme sa racine en noir s'il n'est pas vide.*)
  65. (* Pour un arbre (Red, e, ag, ad) :*)
  66. (* on renvoie un arbre (Black, e, ag, ad)*)
  67. (* Sinon on renvoie l'arbre non modifié.*)
  68. let black_root = function tree ->
  69. match tree with
  70. | Cons (Red, e, ag, ad) -> Cons (Black, e, ag, ad)
  71. | _ -> tree
  72. ;;
  73.  
  74. (*Preuve : Fonction de test pour savoir si la racine de l'arbre est rouge.*)
  75. (* Pour un arbre (Red, e, ag, ad) :*)
  76. (* on renvoie vrai*)
  77. (* Sinon on renvoie faux.*)
  78. let root_is_red = function tree ->
  79. match tree with
  80. | Cons (Red, _, _, _) -> true
  81. | _ -> false
  82. ;;
  83.  
  84. (*Preuve : Fonction de test pour savoir si la racine du fils gauche d'un arbre est rouge.*)
  85. (* Pour un arbre (_, e, ag, ad) avec la racine de ag rouge.*)
  86. (* on renvoie vrai*)
  87. (* Sinon on renvoie faux.*)
  88. let son_left_is_red = function tree ->
  89. match tree with
  90. | Cons (_, _, ag, _) when (root_is_red ag) -> true
  91. | _ -> false
  92. ;;
  93.  
  94. (*Preuve : Fonction de test pour savoir si la racine du fils droit d'un arbre est rouge.*)
  95. (* Pour un arbre (_, e, ag, ad) avec la racine de ad rouge.*)
  96. (* on renvoie vrai*)
  97. (* Sinon on renvoie faux.*)
  98. let son_right_is_red = function tree ->
  99. match tree with
  100. | Cons (_, _, _, ad) when (root_is_red ad) -> true
  101. | _ -> false
  102. ;;
  103.  
  104. (*Preuve : Fonction de test pour savoir si la racine d'un arbre et un de ses fils sont rouges.*)
  105. (* Pour un arbre (Red, e, ag, ad) avec au moins une racine de ag ou ad rouge.*)
  106. (* on renvoie vrai*)
  107. (* Sinon on renvoie faux.*)
  108. let double_red_son = function tree ->
  109. ((root_is_red tree) && ((son_left_is_red tree) || (son_right_is_red tree)))
  110. ;;
  111.  
  112. (*Preuve : Fonction de recoloration d'un arbre.*)
  113. (* Pour un arbre non vide avec des fils non vides :*)
  114. (* on renvoie la racine rouge, et les deux racines des fils noirs.*)
  115. (* Sinon on renvoie l'arbre non modifié.*)
  116. let recoloring_abin = function tree ->
  117. match tree with
  118. | Cons (_, g, Cons (_, p, pl, pr), Cons (_, f, fl, fr)) ->
  119. Cons (Red, g, Cons (Black, p, pl, pr), Cons (Black, f, fl, fr))
  120. | _ -> tree
  121. ;;
  122.  
  123. (*Preuve : Fonction de rotation droite de la racine et de son fils gauche.*)
  124. (* Pour un arbre non vide avec son fils gauche non vide :*)
  125. (* on renvoie la rotation droite.*)
  126. (* Sinon on renvoie l'arbre non modifié.*)
  127. let rotate_right = function tree ->
  128. match tree with
  129. | Cons (cn, n, Cons (cm, m, a1, a2), a3) -> Cons (cm, m, a1, Cons (cn, n, a2, a3))
  130. | _ -> tree
  131. ;;
  132.  
  133. (*Preuve : Fonction de rotation gauche de la racine et de son fils droit.*)
  134. (* Pour un arbre non vide avec son fils droit non vide :*)
  135. (* on renvoie la rotation gauche.*)
  136. (* Sinon on renvoie l'arbre non modifié.*)
  137. let rotate_left = function tree ->
  138. match tree with
  139. | Cons (cm, m, a1, Cons (cn, n, a2, a3)) -> Cons (cn, n, Cons (cm, m, a1, a2), a3)
  140. | _ -> tree
  141. ;;
  142.  
  143. (*Preuve : Fonction de recoloration d'un arbre qui va effectuer une rotation.*)
  144. (* Pour un arbre non vide de racine noire et un fils gauche non vide de racine rouge :*)
  145. (* on renvoie la racine rouge, et la racine du fils gauche noire.*)
  146. (* Pour un arbre non vide de racine noire et un fils droit non vide de racine rouge :*)
  147. (* on renvoie la racine rouge, et la racine du fils droit noire.*)
  148. (* Sinon on renvoie l'arbre non modifié.*)
  149. let recolor_in_rotation = function tree ->
  150. match tree with
  151. | Cons (Black, g, Cons (Red, p, a1, a2), ad) -> Cons (Red, g, Cons (Black, p, a1, a2), ad)
  152. | Cons (Black, g, ag, Cons (Red, p, a1, a2)) -> Cons (Red, g, ag, Cons (Black, p, a1, a2))
  153. | _ -> tree
  154. ;;
  155.  
  156. (*Preuve : Fonction d'équilibre d'un arbre bicolor.*)
  157. (* Pour un arbre non vide de racine noire dont le fils gauche de racine rouge et le fils droit de racine rouge*)
  158. (* ont au moins une fois deux noeuds rouges d'affilé :*)
  159. (* on renvoie l'arbre recoloré avec la racine rouge, et les deux racines des fils noirs.*)
  160. (* *)
  161. (* Pour un arbre non vide de racine noire dont le fils gauche a deux noeuds rouges d'affilé*)
  162. (* et dont la racine du fils gauche du fils gauche est rouge :*)
  163. (* on renvoie la rotation droite de l'arbre de racine rouge, et la racine du fils gauche noire.*)
  164. (* *)
  165. (* Pour un arbre non vide de racine noire dont le fils gauche a deux noeuds rouges d'affilé*)
  166. (* et dont la racine du fils gauche du fils droit est rouge :*)
  167. (* on renvoie l'arbre équilibré de l'arbre de racine noire dont le fils gauche a subi une rotation gauche.*)
  168. (* *)
  169. (* Pour un arbre non vide de racine noire dont le fils droit a deux noeuds rouges d'affilé*)
  170. (* et dont la racine du fils droit du fils gauche est rouge :*)
  171. (* on renvoie l'arbre équilibré de l'arbre de racine noire dont le fils droit a subi une rotation droite.*)
  172. (* *)
  173. (* Pour un arbre non vide de racine noire dont le fils droit a deux noeuds rouges d'affilé*)
  174. (* et dont la racine du fils droit du fils droit est rouge :*)
  175. (* on renvoie la rotation gauche de l'arbre de racine rouge, et la racine du fils droit noire.*)
  176. (* *)
  177. (* Sinon on renvoie l'arbre non modifié.*)
  178. let rec balancing = function tree->
  179. match tree with
  180. | Cons (Black, g, ag, ad) when (((double_red_son ad) || (double_red_son ag))
  181. && (root_is_red ag) && (root_is_red ad))
  182. -> (recoloring_abin tree)
  183. | Cons (Black, g, ag, ad) when ((double_red_son ag) && (son_left_is_red ag))
  184. -> rotate_right (recolor_in_rotation tree)
  185. | Cons (Black, g, ag, ad) when ((double_red_son ag) && (son_right_is_red ag))
  186. -> balancing (Cons (Black, g, (rotate_left ag), ad))
  187. | Cons (Black, g, ag, ad) when ((double_red_son ad) && (son_left_is_red ad))
  188. -> balancing (Cons (Black, g, ag, (rotate_right ad)))
  189. | Cons (Black, g, ag, ad) when ((double_red_son ad) && (son_right_is_red ad))
  190. -> rotate_left (recolor_in_rotation tree)
  191. | _ -> tree
  192. ;;
  193.  
  194. (*Preuve : Fonction d'ajout d'un élèment dans un arbre bicolor.*)
  195. (* Pour un arbre vide :*)
  196. (* on renvoie la racine noire avec l'élèment.*)
  197. (* *)
  198. (* Pour un arbre non vide dont l'élèment est plus petit que l'élèment que l'on souhaite ajouter :*)
  199. (* on renvoie l'arbre équilibré ou l'on a ajouté l'élèment dans le sous-arbre droit.*)
  200. (* *)
  201. (* Pour un arbre non vide dont l'élèment est plus grand que l'élèment que l'on souhaite ajouter :*)
  202. (* on renvoie l'arbre équilibré ou l'on a ajouté l'élèment dans le sous-arbre gauche.*)
  203. (* *)
  204. (* Sinon on renvoie l'arbre non modifié.*)
  205. let ajout_abic = fun abic element ->
  206. let rec aux = fun abic element ->
  207. match abic with
  208. | Empty -> Cons (Red, element, Empty, Empty)
  209. | Cons (c, e, a1, a2) when e < element -> (balancing (Cons (c, e, a1, (aux a2 element))))
  210. | Cons (c, e, a1, a2) when e > element -> (balancing (Cons (c, e, (aux a1 element), a2)))
  211. | _ -> abic
  212. in (black_root (aux abic element))
  213. ;;
  214.  
  215. (**
  216. * Permet de savoir si un élement donné est dans un arbre bicolor donné.
  217. * .@param : element + bicolor_tree
  218. * .@return : bool
  219. *)
  220. let rec bicolor_tree_is_in = fun tree element ->
  221. match tree with
  222. | Empty -> false
  223. | Cons (_, e, tl, _) when e > element -> (bicolor_tree_is_in tl element)
  224. | Cons (_, e, _, tr) when e < element -> (bicolor_tree_is_in tr element)
  225. | _ -> true
  226. ;;
  227.  
  228. (**
  229. * Permet de savoir si un arbre bicolor donné est vide.
  230. * .@param : bicolor_tree
  231. * .@return : bool
  232. *)
  233. let bicolor_tree_is_empty = function tree ->
  234. (tree = Empty)
  235. ;;
  236.  
  237. (**
  238. * Permet de savoir si un arbre est bien un arbre binaire de recherche.
  239. * .@param : bicolor_tree
  240. * .@return : bool
  241. *)
  242. let bicolor_tree_is_binary_search_tree = function tree ->
  243. if (bicolor_tree_is_empty tree) then
  244. true
  245. else
  246. (* Preuve :*)
  247. (* - Pour un arbre (_, e, empty, empty) :*)
  248. (* La valeur booléenne est vraie puisqu'un arbre à un noeud est un arbre binaire de recherche*)
  249. (* Le minumum et le maximum de l'arbre est l'élèment e*)
  250. (* - Pour un arbre (_, e, empty, tr) *)
  251. (* La valeur booléenne correspond à :*)
  252. (* vrai, si la valeur minimale du sous-arbre droit est plus grande que l'élèment e et *)
  253. (* si le sous-arbre droit est un arbre binaire de recherche par induction.*)
  254. (* Le minimum correspond à l'élèment e car tous les elèments du sous-arbre droit*)
  255. (* sont plus grands que l'élèment e par définition d'un arbre binaire de recherche.*)
  256. (* Le maximum correpond à la valeur maximale du sous arbre droit par induction.*)
  257. (* Pour un arbre (_, e, tl, empty) : on peut appliquer la symétrie avec le cas précédent*)
  258. (* Pour un arbre (_, e, tl, tr) : on applique avec les deux cas précédents*)
  259. let rec aux = function
  260. | Cons(_, e, Empty, Empty) ->
  261. (true, e, e)
  262. | Cons(_, e, Empty, tr) ->
  263. let (b, min, max) = (aux tr)
  264. in ((b && (min > e)), e, max)
  265. | Cons(_, e, tl, Empty) ->
  266. let (b, min, max) = (aux tl)
  267. in ((b && (max < e)), min, e)
  268. | Cons(_, e, tl, tr) ->
  269. let (tr, minr, maxr) = (aux tr)
  270. and (tl, minl, maxl) = (aux tl)
  271. in ((tr && tl && (minr > e) && (maxl < e)), minl, maxr)
  272. | Empty -> failwith ""
  273. in
  274. let (b,_,_) = (aux tree)
  275. in b
  276. ;;
  277.  
  278. (**
  279. * Permet de connaître la couleur de la radine d'un arbre coloré donné.
  280. * .@param : bicolor_tree
  281. * .@return : color
  282. *)
  283. let bicolor_tree_color_root = function tree ->
  284. match tree with
  285. | Empty -> failwith "bicolor_tree_color_root: The tree is empty"
  286. | Cons (color, _, _, _) -> color
  287. ;;
  288.  
  289. (**
  290. * Permet de savoir si un arbre est bien un arbre bicolor.
  291. * .@param : bicolor_tree
  292. * .@return : bool
  293. *)
  294. let tree_is_bicolor_tree = function tree ->
  295. if (bicolor_tree_is_empty tree)
  296. then true
  297. else
  298. if (((bicolor_tree_is_binary_search_tree tree) = false)
  299. || ((bicolor_tree_color_root tree) != Black))
  300. then false
  301. else
  302. (* Preuve :*)
  303. (* - Pour un arbre (color, _, empty, empty) :*)
  304. (* La valeur booléenne est vraie puisqu'un arbre à un noeud est un arbre coloré*)
  305. (* Le nombre de noeud correspond à si la couleur de la racine est noire.*)
  306. (* La coleur correspond à la couleur de la racine*)
  307. (* - Pour un arbre (color, _, empty, tr) *)
  308. (* La valeur booléenne correspond à :*)
  309. (* vrai, si la couleur de la racine du sous-arbre gauche est noire*)
  310. (* ou que la couleur de la racine est noire et *)
  311. (* si le nombre de noeuds noirs du sous arbre gauche est égale au nombre*)
  312. (* de noeuds noirs : 0 puisque le sous arbre droit est vide.*)
  313. (* si le sous-arbre gauche est un arbre coloré par induction.*)
  314. (* Le nombre de noeuds noirs correspond au nombre de noeuds noirs du sous arbre gauche*)
  315. (* obtenu par induction + le noeud de la racine de l'arbre s'il est noir.*)
  316. (* Pour un arbre (color, _, tl, empty) : on peut appliquer la symétrie avec le cas précédent*)
  317. (* Pour un arbre (color, _, tl, tr) : on applique avec les deux cas précédents*)
  318. let rec aux = function
  319. | Cons(color, _, Empty, Empty) ->
  320. let nb_node_black =
  321. if (color = Black)
  322. then 1
  323. else 0
  324. in (nb_node_black, true, color)
  325. | Cons(color, _, tl, Empty) ->
  326. let (nb_node_black_tl, bool_tl, color_tl) = (aux tl)
  327. in
  328. let nb_node_black =
  329. if (color = Black) then nb_node_black_tl + 1
  330. else nb_node_black_tl
  331. and b = (bool_tl
  332. && ((color_tl = Black) || (color = Black))
  333. && (nb_node_black_tl = 0))
  334. in (nb_node_black, b, color)
  335. | Cons(color, _, Empty, tr) ->
  336. let (nb_node_black_tr, bool_tr, color_tr) = (aux tr)
  337. in
  338. let nb_node_black =
  339. if (color = Black)
  340. then nb_node_black_tr + 1
  341. else nb_node_black_tr
  342. and b = (bool_tr
  343. && ((color_tr = Black) || (color = Black))
  344. && (nb_node_black_tr = 0))
  345. in (nb_node_black, b, color)
  346. | Cons (color, _, tl, tr) ->
  347. let (nb_node_black_tl, bool_tl, color_tl) = (aux tl)
  348. and (nb_node_black_tr, bool_tr, color_tr) = (aux tr)
  349. in
  350. let b = (bool_tl && bool_tr
  351. && (nb_node_black_tl = nb_node_black_tr))
  352. and nb_node_black =
  353. if (color = Black)
  354. then nb_node_black_tl + 1
  355. else nb_node_black_tl
  356. in (nb_node_black, b, color)
  357. | Empty -> failwith "bicolor_tree_color_root: Error"
  358. in
  359. let (_, b, _) = (aux tree)
  360. in b
  361. ;;
  362.  
  363. (* Test *)
  364.  
  365. let rec ajout_n_random_element_in_abic = fun abic n ->
  366. if (n <= 0) then abic
  367. else (ajout_n_random_element_in_abic
  368. (ajout_abic abic (Random.int 100))
  369. (n - 1))
  370. ;;
  371.  
  372. let test = fun n ->
  373. let a = (ajout_n_random_element_in_abic Empty n)
  374. in (tree_is_bicolor_tree a)
  375. ;;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement