00001 /* LIBGUL - Geometry Utility Library
00002 * Copyright (C) 1998-1999 Norbert Irmer
00003 *
00004 * This library is free software; you can redistribute it and/or
00005 * modify it under the terms of the GNU Library General Public
00006 * License as published by the Free Software Foundation; either
00007 * version 2 of the License, or (at your option) any later version.
00008 *
00009 * This library is distributed in the hope that it will be useful,
00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 * Library General Public License for more details.
00013 *
00014 * You should have received a copy of the GNU Library General Public
00015 * License along with this library; if not, write to the
00016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017 * Boston, MA 02111-1307, USA.
00018 */
00019
00020 #ifndef GUMA_SORTING_H
00021 #define GUMA_SORTING_H
00022
00023 namespace guma {
00024
00025 /***************************************************************
00026
00027 BALANCED BINARY TREE (see Knuth: "Sorting and Searching")
00028
00029 ***************************************************************/
00030
00031 /*---------------------------------------------------------------
00032 Structure for the nodes of a balanced binary tree
00033 ----------------------------------------------------------------*/
00034
00035 typedef struct bbt_node
00036 {
00037 void *key;
00038
00039 struct
00040 {
00041 int b : 2;
00042 int l : 2;
00043 }F;
00044
00045 struct bbt_node *left;
00046 struct bbt_node *right;
00047 struct bbt_node *parent;
00048 }
00049 BBTNode;
00050
00051 /*-------------------------------------------------------------
00052 Creates an empty balanced binary tree
00053 ------------------------------------------------------------*/
00054 GULAPI void InitBBT( BBTNode *head );
00055
00056 /*----------------------------------------------------------------------
00057 Search for an element in a balanced binary tree. If the element was found,
00058 the address of its node is returned, otherwise the position (address of node
00059 and side) in the tree is returned, under which the element would be
00060 inserted.
00061 ------------------------------------------------------------------------*/
00062 GULAPI int SearchElementInBBT( BBTNode *head, void *key,
00063 int compare( void *, void * ),
00064 BBTNode **element );
00065 /* ---------------------------------------------------------------
00066 Find the successor of a given element in a balanced binary tree
00067 ----------------------------------------------------------------- */
00068 GULAPI BBTNode *SearchSuccessorInBBT( BBTNode *element, BBTNode *head );
00069
00070 /* ---------------------------------------------------------------
00071 Find the predecessor of a given element in a balanced binary tree
00072 ----------------------------------------------------------------- */
00073 GULAPI BBTNode *SearchPredecessorInBBT( BBTNode *element, BBTNode *head );
00074
00075 /*------------------------------------------------------------------------
00076 Inserts a node 'element' into a balanced binary tree, given by 'head'.
00077 The node is inserted under the node 'where' on the side 'side'.
00078 (side == -1 => left, side == 1 => right )
00079 ------------------------------------------------------------------------*/
00080 GULAPI void InsertElementIntoBBT( BBTNode *element,
00081 BBTNode *where, int side, BBTNode *head );
00082
00083 /*------------------------------------------------------------------------
00084 Removes a node 'element' from a balanced binary tree 'head'.
00085 The tree will get rebalanced, if necessary.
00086 ------------------------------------------------------------------------*/
00087 GULAPI void DeleteElementFromBBT( BBTNode *element, BBTNode *head );
00088
00089 /*------------------------------------------------------------------------
00090 Dump BBT Tree (for debugging)
00091 ------------------------------------------------------------------------*/
00092 GULAPI void DumpBBTTree( BBTNode *node, int level,
00093 void dumpkey_func( void * ) );
00094 GULAPI void DumpBBTNode( BBTNode *node, int level );
00095
00096
00097 /*----------------------------------------------------------
00098 Heapsort (see "Numerical Recipes in C", or Knuth)
00099 -----------------------------------------------------------*/
00100 GULAPI void HeapSort( size_t nelem, size_t elsize, void *elptr,
00101 int (*usrfunc)( void *, void *, void *), void *usrdata );
00102 GULAPI void PtrHeapSort( size_t nelem, void **elptr,
00103 int (*usrfunc)( void *, void *, void *), void *usrdata );
00104
00105 /*----------------------------------------------------------
00106 Heapsort as template
00107 -----------------------------------------------------------*/
00108 template< class T >
00109 inline void _heapsort( int nA, gul::Ptr<T>& A )
00110 {
00111 gul::Ptr<T>& ra = A;
00112 T rra;
00113 int n = nA, l, ir, i, j;
00114
00115 if( n < 2 ) return;
00116 l = (n >> 1) + 1;
00117 ir = n;
00118
00119 for(;;)
00120 {
00121 if( l > 1 )
00122 {
00123 rra = ra[l-2];
00124 l--;
00125 }
00126 else
00127 {
00128 rra = ra[ir-1];
00129 ra[ir-1] = ra[0];
00130
00131 if( --ir == 1 )
00132 {
00133 ra[0] = rra;
00134 break;
00135 }
00136 }
00137 i = l;
00138 j = l+l;
00139
00140 while( j <= ir )
00141 {
00142 if( (j < ir) && (ra[j-1] < ra[j]) )
00143 j++;
00144
00145 if( rra < ra[j-1] )
00146 {
00147 ra[i-1] = ra[j-1];
00148 i = j;
00149 j <<= 1;
00150 }
00151 else
00152 j = ir + 1;
00153 }
00154
00155 ra[i-1] = rra;
00156 }
00157 }
00158 // these are often used, so they are instantiated in the library
00159 GULAPI void heapsort( int nA, gul::Ptr<void *>& A );
00160 GULAPI void heapsort( int nA, gul::Ptr<int>& A );
00161
00162 /*------------------------------------------------------------------
00163 Binary search in a sorted array. Returns position of the searched
00164 element, or -1 if the array doesn't contains the element
00165 ------------------------------------------------------------------*/
00166
00167 template< class T >
00168 inline int _BinarySearch( T x, int nA, const gul::Ptr<T>& A )
00169 {
00170 int mid,right,left;
00171
00172 if( nA == 0 ) return -1;
00173
00174 if( A[0] >= x )
00175 {
00176 if( A[0] > x ) return -1;
00177 return 0;
00178 }
00179 if( A[nA-1] <= x )
00180 {
00181 if( A[nA-1] < x ) return -1;
00182 return nA-1;
00183 }
00184
00185 left = 0;
00186 right = nA;
00187 mid = (left+right)/2;
00188
00189 while( (mid!=left) && (mid!=right) )
00190 {
00191 if( A[mid] == x )
00192 break;
00193 else if( A[mid] > x )
00194 {
00195 right = mid;
00196 mid = (left+right)>>1;
00197 }
00198 else
00199 {
00200 left = mid;
00201 mid = (left+right)>>1;
00202 }
00203 }
00204 if( A[mid] != x ) return -1;
00205
00206 return mid;
00207 }
00208
00209 // these are often used, so they are instantiated in the library
00210 GULAPI int BinarySearch( int x, int nA, const gul::Ptr<int>& A );
00211 GULAPI int BinarySearch( void *x, int nA, const gul::Ptr<void *>& A );
00212
00213 /*------------------------------------------------------------------
00214 another binary search routine, slightly different from the above.
00215 it returns the indices of the nearest left and right neighbor elements,
00216 or -1 if one of these doesn't exists
00217 ------------------------------------------------------------------*/
00218 template< class T >
00219 inline int _BinarySearch( T x, int nA, const gul::Ptr<T>& A,
00220 int *rleft, int *rright )
00221 {
00222 int mid,right,left;
00223
00224 if( nA == 0 )
00225 {
00226 *rleft = -1;
00227 *rright = -1;
00228 return -1;
00229 }
00230
00231 if( A[0] >= x )
00232 {
00233 *rright = 0;
00234
00235 if( A[0] > x )
00236 {
00237 *rleft = -1;
00238 return -1;
00239 }
00240 else
00241 {
00242 *rleft = 0;
00243 return 0;
00244 }
00245 }
00246
00247 if( A[nA-1] <= x )
00248 {
00249 *rleft = nA-1;
00250
00251 if( A[nA-1] < x )
00252 {
00253 *rright = -1;
00254 return -1;
00255 }
00256 else
00257 {
00258 *rright = nA-1;
00259 return nA-1;
00260 }
00261 }
00262
00263 left = 0;
00264 right = nA;
00265 mid = (left+right)/2;
00266
00267 while( (mid!=left) && (mid!=right) )
00268 {
00269 if( A[mid] == x )
00270 break;
00271 else if( A[mid] > x )
00272 {
00273 right = mid;
00274 mid = (left+right)>>1;
00275 }
00276 else
00277 {
00278 left = mid;
00279 mid = (left+right)>>1;
00280 }
00281 }
00282 if( A[mid] != x )
00283 {
00284 *rleft = left;
00285 *rright = right;
00286 return -1;
00287 }
00288 else
00289 {
00290 *rleft = mid;
00291 *rright = mid;
00292 }
00293
00294 return mid;
00295 }
00296
00297
00298
00299 }
00300
00301 #endif
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001