⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splay-set-fn.sml

📁 这是我们参加06年全国开源软件的竞赛作品
💻 SML
字号:
(* splay-set-fn.sml * * COPYRIGHT (c) 1993 by AT&T Bell Laboratories.  See COPYRIGHT file for details. * * Functor implementing ordered sets using splay trees. * *)functor SplaySetFn (K : ORD_KEY) : ORD_SET =  struct    structure Key = K    open SplayTree    type item = K.ord_key      datatype set =         EMPTY      | SET of {        root : item splay ref,        nobj : int      }    fun cmpf k = fn k' => K.compare(k',k)    val empty = EMPTY    fun singleton v = SET{root = ref(SplayObj{value=v,left=SplayNil,right=SplayNil}),nobj=1}    	(* Primitive insertion.	 *)    fun insert (v,(nobj,root)) =          case splay (cmpf v, root) of            (EQUAL,SplayObj{value,left,right}) =>               (nobj,SplayObj{value=v,left=left,right=right})          | (LESS,SplayObj{value,left,right}) =>               (nobj+1,               SplayObj{                 value=v,                 left=SplayObj{value=value,left=left,right=SplayNil},                 right=right})          | (GREATER,SplayObj{value,left,right}) =>               (nobj+1,               SplayObj{                  value=v,                  left=left,                  right=SplayObj{value=value,left=SplayNil,right=right}})          | (_,SplayNil) => (1,SplayObj{value=v,left=SplayNil,right=SplayNil})	(* Add an item.  	 *)    fun add (EMPTY,v) = singleton v      | add (SET{root,nobj},v) = let          val (cnt,t) = insert(v,(nobj,!root))          in            SET{nobj=cnt,root=ref t}          end    fun add' (s, x) = add(x, s)	(* Insert a list of items.	 *)    fun addList (set,[]) = set      | addList (set,l) = let          val arg = case set of EMPTY => (0,SplayNil)                               | SET{root,nobj} => (nobj,!root)          val (cnt,t) = List.foldl insert arg l          in            SET{nobj=cnt,root=ref t}          end	(* Remove an item.         * Raise LibBase.NotFound if not found	 *)    fun delete (EMPTY,_) = raise LibBase.NotFound      | delete (SET{root,nobj},key) =          case splay (cmpf key, !root) of            (EQUAL,SplayObj{value,left,right}) =>               if nobj = 1 then EMPTY              else SET{root=ref(join(left,right)),nobj=nobj-1}          | (_,r) => (root := r; raise LibBase.NotFound)  (* return true if the item is in the set *)    fun member (EMPTY, key) = false      | member (SET{root,nobj}, key) = (case splay (cmpf key, !root)           of (EQUAL, r) => (root := r; true)            | (_, r) => (root := r; false)	  (* end case *))    fun isEmpty EMPTY = true      | isEmpty _ = false    local      fun member (x,tree) = let            fun mbr SplayNil = false              | mbr (SplayObj{value,left,right}) =                  case K.compare(x,value) of                    LESS => mbr left                  | GREATER => mbr right                  | _ => true          in mbr tree end        (* true if every item in t is in t' *)      fun treeIn (t,t') = let            fun isIn SplayNil = true              | isIn (SplayObj{value,left=SplayNil,right=SplayNil}) =                  member(value, t')              | isIn (SplayObj{value,left,right=SplayNil}) =                  member(value, t') andalso isIn left              | isIn (SplayObj{value,left=SplayNil,right}) =                  member(value, t') andalso isIn right              | isIn (SplayObj{value,left,right}) =                  member(value, t') andalso isIn left andalso isIn right            in              isIn t            end    in    fun equal (SET{root=rt,nobj=n},SET{root=rt',nobj=n'}) =          (n=n') andalso treeIn (!rt,!rt')      | equal (EMPTY, EMPTY) = true      | equal _ = false    fun isSubset (SET{root=rt,nobj=n},SET{root=rt',nobj=n'}) =          (n<=n') andalso treeIn (!rt,!rt')      | isSubset (EMPTY,_) = true      | isSubset _ = false    end    local      fun next ((t as SplayObj{right, ...})::rest) = (t, left(right, rest))	| next _ = (SplayNil, [])      and left (SplayNil, rest) = rest	| left (t as SplayObj{left=l, ...}, rest) = left(l, t::rest)    in    fun compare (EMPTY, EMPTY) = EQUAL      | compare (EMPTY, _) = LESS      | compare (_, EMPTY) = GREATER      | compare (SET{root=s1, ...}, SET{root=s2, ...}) = let	  fun cmp (t1, t2) = (case (next t1, next t2)		 of ((SplayNil, _), (SplayNil, _)) => EQUAL		  | ((SplayNil, _), _) => LESS		  | (_, (SplayNil, _)) => GREATER		  | ((SplayObj{value=e1, ...}, r1), (SplayObj{value=e2, ...}, r2)) => (		      case Key.compare(e1, e2)		       of EQUAL => cmp (r1, r2)			| order => order		      (* end case *))		(* end case *))	  in	    cmp (left(!s1, []), left(!s2, []))	  end    end (* local *)	(* Return the number of items in the table *)    fun numItems EMPTY = 0      | numItems (SET{nobj,...}) = nobj    fun listItems EMPTY = []      | listItems (SET{root,...}) =        let fun apply (SplayNil,l) = l              | apply (SplayObj{value,left,right},l) =                  apply(left, value::(apply (right,l)))        in          apply (!root,[])        end    fun split (value,s) =          case splay(cmpf value, s) of            (EQUAL,SplayObj{value,left,right}) => (SOME value, left, right)          | (LESS,SplayObj{value,left,right}) => (NONE, SplayObj{value=value,left=left,right=SplayNil},right)          | (GREATER,SplayObj{value,left,right}) => (NONE, left, SplayObj{value=value,right=right,left=SplayNil})          | (_,SplayNil) => (NONE, SplayNil, SplayNil)    fun intersection (EMPTY,_) = EMPTY      | intersection (_,EMPTY) = EMPTY      | intersection (SET{root,...},SET{root=root',...}) =          let fun inter(SplayNil,_) = (SplayNil,0)                | inter(_,SplayNil) = (SplayNil,0)                | inter(s, SplayObj{value,left,right}) =                    case split(value,s) of                      (SOME v, l, r) =>                        let val (l',lcnt) = inter(l,left)                            val (r',rcnt) = inter(r,right)                        in                          (SplayObj{value=v,left=l',right=r'},lcnt+rcnt+1)                        end                    | (_,l,r) =>                        let val (l',lcnt) = inter(l,left)                            val (r',rcnt) = inter(r,right)                        in                          (join(l',r'),lcnt+rcnt)                        end          in            case inter(!root,!root') of              (_,0) => EMPTY            | (root,cnt) => SET{root = ref root, nobj = cnt}          end    fun count st =         let fun cnt(SplayNil,n) = n               | cnt(SplayObj{left,right,...},n) = cnt(left,cnt(right,n+1))         in           cnt(st,0)         end    fun difference (EMPTY,_) = EMPTY      | difference (s,EMPTY) = s      | difference (SET{root,...}, SET{root=root',...}) =          let fun diff(SplayNil,_) = (SplayNil,0)                | diff(s,SplayNil) = (s, count s)                | diff(s,SplayObj{value,right,left}) =                    let val (_,l,r) = split(value,s)                        val (l',lcnt) = diff(l,left)                        val (r',rcnt) = diff(r,right)                    in                      (join(l',r'),lcnt+rcnt)                    end          in            case diff(!root,!root') of              (_,0) => EMPTY            | (root,cnt) => SET{root = ref root, nobj = cnt}          end    fun union (EMPTY,s) = s      | union (s,EMPTY) = s      | union (SET{root,...}, SET{root=root',...}) =          let fun uni(SplayNil,s) = (s,count s)                | uni(s,SplayNil) = (s, count s)                | uni(s,SplayObj{value,right,left}) =                    let val (_,l,r) = split(value,s)                        val (l',lcnt) = uni(l,left)                        val (r',rcnt) = uni(r,right)                    in                      (SplayObj{value=value,right=r',left=l'},lcnt+rcnt+1)                    end              val (root,cnt) = uni(!root,!root')          in            SET{root = ref root, nobj = cnt}          end    fun map f EMPTY = EMPTY      | map f (SET{root, ...}) = let	  fun mapf (acc, SplayNil) = acc	    | mapf (acc, SplayObj{value,left,right}) =		mapf (add (mapf (acc, left), f value), right)	  in	    mapf (EMPTY, !root)	  end    fun app af EMPTY = ()      | app af (SET{root,...}) =          let fun apply SplayNil = ()                | apply (SplayObj{value,left,right}) =                    (apply left; af value; apply right)          in apply (!root) end(*    fun revapp af (SET{root,...}) =          let fun apply SplayNil = ()                | apply (SplayObj{value,left,right}) =                     (apply right; af value; apply left)          in apply (!root) end*)	(* Fold function *)    fun foldr abf b EMPTY = b      | foldr abf b (SET{root,...}) =          let fun apply (SplayNil, b) = b                | apply (SplayObj{value,left,right},b) =                    apply(left,abf(value,apply(right,b)))        in          apply (!root,b)        end    fun foldl abf b EMPTY = b      | foldl abf b (SET{root,...}) =          let fun apply (SplayNil, b) = b                | apply (SplayObj{value,left,right},b) =                    apply(right,abf(value,apply(left,b)))        in          apply (!root,b)        end    fun filter p EMPTY = EMPTY      | filter p (SET{root,...}) = let          fun filt (SplayNil,tree) = tree            | filt (SplayObj{value,left,right},tree) = let                val t' = filt(right,filt(left,tree))                in                  if p value then insert(value,t')                  else t'                end          in            case filt(!root,(0,SplayNil)) of              (0,_) => EMPTY            | (cnt,t) => SET{nobj=cnt,root=ref t}          end    fun exists p EMPTY = false      | exists p (SET{root,...}) = let          fun ex SplayNil = false            | ex (SplayObj{value=v,left=l,right=r}) =                if p v then true                else case ex l of                       false => ex r                     | _ => true           in            ex (!root)          end    fun find p EMPTY = NONE      | find p (SET{root,...}) = let          fun ex SplayNil = NONE            | ex (SplayObj{value=v,left=l,right=r}) =                if p v then SOME v                else case ex l of                       NONE => ex r                     | a => a           in            ex (!root)          end  end (* SplaySet *)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -