File: unionfind.ml

package info (click to toggle)
why 2.13-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 12,608 kB
  • ctags: 16,817
  • sloc: ml: 102,672; java: 7,173; ansic: 4,439; makefile: 1,409; sh: 585
file content (117 lines) | stat: -rw-r--r-- 3,153 bytes parent folder | download | duplicates (2)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
(**************************************************************************)
(*                                                                        *)
(*  Ocamlgraph: a generic graph library for OCaml                         *)
(*  Copyright (C) 2004-2007                                               *)
(*  Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles        *)
(*                                                                        *)
(*  This software is free software; you can redistribute it and/or        *)
(*  modify it under the terms of the GNU Library General Public           *)
(*  License version 2, with the special exception on linking              *)
(*  described in file LICENSE.                                            *)
(*                                                                        *)
(*  This software is distributed in the hope that it will be useful,      *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *)
(*                                                                        *)
(**************************************************************************)

(* $Id:$ *)

module type HashedOrderedType = sig
  type t
  val equal : t -> t -> bool
  val hash : t -> int 
  val compare : t -> t -> int 
end

module type S = sig
  type elt
  type t
    
  val init : elt list -> t
  val find : elt -> t -> elt
  val union : elt -> elt -> t -> unit
end

module Make(X:HashedOrderedType) = struct

  type elt = X.t

  module H = Hashtbl.Make(X)
  
  type cell = {
    mutable c : int;
    data : elt;
    mutable father : cell
  }
  
  type t = cell H.t (* a forest *)

  let init l = 
    let h = H.create 997 in
    List.iter 
      (fun x ->
         let rec cell = { c = 0; data = x; father = cell } in 
	 H.add h x cell) 
      l;
    h

  let rec find_aux cell = 
    if cell.father == cell then 
      cell
    else 
      let r = find_aux cell.father in 
      cell.father <- r; 
      r

  let find x h = (find_aux (H.find h x)).data

  let union x y h = 
    let rx = find_aux (H.find h x) in
    let ry = find_aux (H.find h y) in
    if rx != ry then begin
      if rx.c > ry.c then
        ry.father <- rx
      else if rx.c < ry.c then
        rx.father <- ry
      else begin
        rx.c <- rx.c + 1;
        ry.father <- rx
      end
    end
end

(*** test ***)
(***

module M = Make (struct 
        type t = int let 
        hash = Hashtbl.hash 
        let compare = compare 
        let equal = (=) 
    end)

open Printf

let saisir s  = 
        printf "%s = " s; flush stdout;
        let x = read_int () in
        x

let h = M.init [0;1;2;3;4;5;6;7;8;9] 
let () = if not !Sys.interactive then 
    while true do 
        printf "1) find\n2) union\n";
        match read_int () with
            1 -> begin
                let x = saisir "x" in
                printf "%d\n" (M.find x h) 
            end
          | 2 -> begin
                let x, y = saisir "x", saisir "y" in
                M.union x y h
            end
          | _ -> ()
    done

***)