00001 //-*-c++-*- 00002 // ==================================================================== 00003 // ==================================================================== 00004 // 00005 // Module: opt_union_find.h 00006 // $Revision: 1.1.1.1 $ 00007 // $Date: 2005/10/21 19:00:00 $ 00008 // $Author: marcel $ 00009 // $Source: /proj/osprey/CVS/open64/osprey1.0/be/opt/opt_union_find.h,v $ 00010 // 00011 // ==================================================================== 00012 // 00013 // Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00014 // 00015 // This program is free software; you can redistribute it and/or modify 00016 // it under the terms of version 2 of the GNU General Public License as 00017 // published by the Free Software Foundation. 00018 // 00019 // This program is distributed in the hope that it would be useful, but 00020 // WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 // 00023 // Further, this software is distributed without any warranty that it 00024 // is free of the rightful claim of any third person regarding 00025 // infringement or the like. Any license provided herein, whether 00026 // implied or otherwise, applies only to this software file. Patent 00027 // licenses, if any, provided herein do not apply to combinations of 00028 // this program with other software, or any other product whatsoever. 00029 // 00030 // You should have received a copy of the GNU General Public License 00031 // along with this program; if not, write the Free Software Foundation, 00032 // Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00033 // 00034 // Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00035 // Mountain View, CA 94043, or: 00036 // 00037 // http://www.sgi.com 00038 // 00039 // For further information regarding this notice, see: 00040 // 00041 // http://oss.sgi.com/projects/GenInfo/NoticeExplan 00042 // 00043 // ==================================================================== 00044 // 00045 // Description: 00046 // 00047 // The template pair 00048 // U_F_REP<ELEMENT_TYPE> and U_F_ELEMENT<ELEMENT_TYPE> 00049 // efficiently implements sets with two operators: find representative 00050 // and set union. 00051 // 00052 // U_F_ELEMENT<ELEMENT_TYPE> is the type of an element of a set. 00053 // Each set is assigned an object of type U_F_REP<ELEMENT_TYPE> 00054 // which acts as a representation for that set. Also, each 00055 // representative U_F_REP<ELEMENT_TYPE> holds a pointer to an object 00056 // of type ELEMENT_TYPE. 00057 // 00058 // ELEMENT_TYPE * 00059 // U_F_REP<ELEMENT_TYPE>::Representative(void) const; 00060 // returns a pointer to its associated object of type ELEMENT_TYPE. 00061 // 00062 // U_F_REP<ELEMENT_TYPE> * 00063 // U_F_REP<ELEMENT_TYPE>::Union(U_F_REP<ELEMENT_TYPE> &that); 00064 // merges this set and that set, and returns a pointer to the 00065 // resulting union set representative. (The representative of a 00066 // union of sets is chosen to be one of the representatives of the 00067 // sets being merged. 00068 // 00069 // U_F_REP<ELEMENT_TYPE> * 00070 // U_F_ELEMENT<ELEMENT_TYPE>::Find(void); 00071 // returns a pointer to the representative of the set containing 00072 // this element. 00073 // 00074 // Implementation: 00075 // 00076 // The U_F_ELEMENT objects in each set are arranged in a tree. Each 00077 // U_F_ELEMENT has a parent U_F_ELEMENT, except for the root, which has 00078 // a pointer to the representative U_F_REP object for that set. 00079 // 00080 // ==================================================================== 00081 // ==================================================================== 00082 00083 00084 #ifndef opt_union_find_INCLUDED 00085 #define opt_union_find_INCLUDED "opt_union_find.h" 00086 00087 #include "defs.h" 00088 00089 00090 // ==================================================================== 00091 00092 00093 template <class ELEMENT_TYPE> class U_F_ELEMENT; 00094 00095 template <class ELEMENT_TYPE> 00096 class U_F_REP { 00097 friend class U_F_ELEMENT<ELEMENT_TYPE>; 00098 protected: 00099 00100 // _height is an estimate of the depth of the tree of U_F_ELEMENT 00101 // class objects. It is used as a heuristic during set union 00102 // operations to minimize the depth of the resulting set. 00103 // _representative points to the ELEMENT_TYPE object representative 00104 // for this set. 00105 00106 UINT _height; 00107 ELEMENT_TYPE *_representative; 00108 00109 public: 00110 U_F_REP(void) : _height(0), _representative(NULL) { } 00111 00112 void Set_representative(ELEMENT_TYPE *representative) 00113 { _representative = representative; } 00114 00115 void Set_height(UINT height) 00116 { _height = height; } 00117 00118 ELEMENT_TYPE *Representative(void) const 00119 { 00120 Is_True(_representative == NULL || 00121 _representative->Null_parent(), 00122 ("UNION_FIND: Set representative must not have parent")); 00123 return _representative; 00124 } 00125 00126 U_F_REP<ELEMENT_TYPE> *Union(U_F_REP<ELEMENT_TYPE> &); 00127 }; 00128 00129 00130 // ==================================================================== 00131 00132 00133 template <class ELEMENT_TYPE> 00134 class U_F_ELEMENT { 00135 private: 00136 00137 // _parent is the parent node of this U_F_ELEMENT in this set tree. 00138 // _set_rep is the representative of this set iff this U_F_ELEMENT 00139 // is the root of its set tree (iff _parent == NULL). 00140 00141 U_F_ELEMENT *_parent; 00142 U_F_REP<ELEMENT_TYPE> *_set_rep; 00143 00144 public: 00145 U_F_ELEMENT(void) : _parent(NULL), _set_rep(NULL) { } 00146 00147 void Put_in_set(U_F_REP<ELEMENT_TYPE> *set) 00148 { 00149 FmtAssert(_parent == NULL && 00150 _set_rep == NULL, 00151 ("U_F_ELEMENT::Put_in_set: Element already " 00152 "belongs somewhere")); 00153 if (set->Representative() == NULL) { 00154 // We're the first element of the set. 00155 set->Set_representative((ELEMENT_TYPE *) this); 00156 _set_rep = set; 00157 } 00158 else { 00159 _parent = set->Representative(); 00160 } 00161 } 00162 00163 void Set_parent(U_F_ELEMENT *parent) { _parent = parent; } 00164 00165 BOOL Null_parent(void) const { return _parent == NULL; } 00166 00167 #if Is_True_On 00168 void Clear_set_rep(void) { _set_rep = NULL; } 00169 #endif 00170 00171 U_F_REP<ELEMENT_TYPE> *Find(void); 00172 }; 00173 00174 00175 // ==================================================================== 00176 00177 00178 // here starts definition of templatized routines 00179 00180 template <class ELEMENT_TYPE> U_F_REP<ELEMENT_TYPE> * 00181 U_F_REP<ELEMENT_TYPE>::Union(U_F_REP<ELEMENT_TYPE> &that) 00182 { 00183 if (Representative() != that.Representative()) { 00184 U_F_REP<ELEMENT_TYPE> *parent, *child; 00185 00186 if (_height < that._height) { 00187 parent = &that; 00188 child = this; 00189 } 00190 else { 00191 parent = this; 00192 child = &that; 00193 } 00194 00195 if (_height == that._height) { 00196 ++(parent->_height); 00197 } 00198 00199 #if Is_True_On 00200 // For debugging, make sure we can see that the child's 00201 // representative is no longer the root of a tree. 00202 child->Representative()->Clear_set_rep(); 00203 #endif 00204 00205 child->Representative()->Set_parent(parent->Representative()); 00206 00207 Set_representative(parent->Representative()); 00208 Set_height(parent->_height); 00209 // We really should free the memory associated with *child here. 00210 return parent; 00211 } 00212 else { 00213 FmtAssert(this == &that, 00214 ("U_F_REP: Different sets must have different " 00215 "representatives")); 00216 return this; 00217 } 00218 } 00219 00220 00221 template <class ELEMENT_TYPE> U_F_REP<ELEMENT_TYPE> * 00222 U_F_ELEMENT<ELEMENT_TYPE>::Find(void) 00223 { 00224 if (_parent == NULL) { 00225 Is_True(_set_rep == NULL || 00226 _set_rep->Representative() == this, 00227 ("UNION_FIND::Find: Inconsistent representative")); 00228 return _set_rep; 00229 } 00230 else { 00231 Is_True(_parent != this, 00232 ("UNION_FIND: Endless find loop")); 00233 U_F_REP<ELEMENT_TYPE> *retval = _parent->Find(); 00234 Is_True(retval != NULL, 00235 ("UNION_FIND: Elements in no set may not be connected.")); 00236 _parent = retval->Representative(); 00237 return retval; 00238 } 00239 } 00240 00241 // ==================================================================== 00242 00243 #endif
1.5.6