00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#ifndef MN_OS_DICTIONARY_H
00025
#define MN_OS_DICTIONARY_H
00026
00027
#include "dict_both.h"
00028
#include <assert.h>
00029
#include <stdlib.h>
00030
#include <time.h>
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
#undef DEFINE_COMPARE
00041
#define DEFINE_COMPARE(T) \
00042
extern int compare (const T& x, const T& y);
00043
00044
DEFINE_COMPARE(
int)
00045 DEFINE_COMPARE(
unsigned int)
00046 DEFINE_COMPARE(
long)
00047 DEFINE_COMPARE(
unsigned long)
00048 #ifdef HAVE_KEYWORD_BOOL
00049 DEFINE_COMPARE(
bool)
00050 #endif
00051 DEFINE_COMPARE(
char)
00052 DEFINE_COMPARE(
unsigned char)
00053 DEFINE_COMPARE(
float)
00054
00055
00062 template <class K, class I> class
dictionary
00063 {
00064
00065
public:
00066 typedef void*
item;
00067
00068
private:
00069
typedef _d_dic_item<K,I>*
DI;
00070
00071
00072
private:
00073
int _size;
00074 DI root;
00075 int (*cmp_ptr) (
const K &,
const K &);
00076
00077
00078
public:
00079 dictionary (){
00080 _size = 0;
00081 root = NULL;
00082 cmp_ptr = &
compare;
00083 srand((
unsigned int) time(NULL));
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 ~dictionary();
00097
00098
00099
public:
00100 K key (
const void* it)
const;
00101 I inf (
const void* it)
const;
00102 I& operator[] (
const void* it)
const;
00103
void* insert (
const K k,
const I i);
00104
void* lookup (
const K k)
const;
00105 I access (
const K k)
const;
00106
void del (
const K k);
00107
void del_item (
const void* it);
00108
void change_inf (
const void* it,
const I i);
00109 void clear () {
00110
if (root != NULL) {
00111 clear_helper(root);
00112 }
00113 root = NULL;
00114 }
00115
int size () const;
00116
bool empty () const;
00117
void* first_item (
void* start = NULL ) const;
00118
void* last_item () const;
00119
void* next_item (const
void* it) const;
00120 private:
00121
void clear_helper (DI it);
00122 DI pos_finder (const K k) const;
00123
void rotation (DI it);
00124 };
00125
00128
00129 template<class K, class I> dictionary<K,I>::~dictionary () {
00130 clear();
00131 }
00132
00133
template<
class K,
class I>
00134 inline void*
dictionary<K,I>::first_item (
void* start )
const {
00135 DI lastit = NULL;
00136 DI it = (start == NULL) ? root : (DI)start;
00137
while (it != NULL) {
00138 lastit = it;
00139 it = it->
left;
00140 }
00141
return (
void*)lastit;
00142 }
00143
00144
template<
class K,
class I>
00145 inline void*
dictionary<K,I>::last_item ()
const {
00146 DI lastit = NULL;
00147 DI it = root;
00148
while (it != NULL) {
00149 lastit = it;
00150 it = it->
right;
00151 }
00152
return (
void*)lastit;
00153 }
00154
00155
template<
class K,
class I>
00156 inline K
dictionary<K,I>::key (
const void* it)
const {
00157
return ((DI)it)->key;
00158 }
00159
00160
template<
class K,
class I>
00161 inline I
dictionary<K,I>::inf (
const void* it)
const {
00162
return ((DI)it)->inf;
00163 }
00164
00165
template<
class K,
class I>
00166 inline I&
dictionary<K,I>::operator[] (
const void* it)
const {
00167
return (((DI)it)->inf);
00168 }
00169
00170
template<
class K,
class I>
00171 inline void*
dictionary<K,I>::lookup (
const K k)
const {
00172
if (root == NULL)
return NULL;
00173
else {
00174 DI it = pos_finder(k);
00175
return (cmp_ptr(it->
key, k) == 0) ? (
void*)it : NULL;
00176 }
00177 }
00178
00179
template<
class K,
class I>
00180 inline I
dictionary<K,I>::access (
const K k)
const {
00181
return inf(
lookup(k));
00182 }
00183
00184
template<
class K,
class I>
00185 inline void dictionary<K,I>::del (
const K k) {
00186
void* it =
lookup(k);
00187
if (it != NULL)
del_item(it);
00188 }
00189
00190
template<
class K,
class I>
00191 inline void dictionary<K,I>::change_inf (
const void* it,
const I i) {
00192 ((DI)it)->inf = i;
00193 }
00194
00195
template<
class K,
class I>
00196 inline int dictionary<K,I>::size ()
const {
00197
return _size;
00198 }
00199
00200
template<
class K,
class I>
00201 inline bool dictionary<K,I>::empty ()
const {
00202
return (_size==0) ?
true :
false;
00203 }
00204
00205
template<
class K,
class I>
00206
inline void dictionary<K,I>::rotation (DI it) {
00207
00208
while ( (it->father == NULL) ?
false : (it->index < it->father->index) ) {
00209 DI father = it->
father;
00210
00211 DI opa = father->
father;
00212
if (opa == NULL) {
00213
00214 root = it;
00215 it->
father = NULL;
00216 }
else {
00217
if (opa->left == father) opa->left = it;
else opa->right = it;
00218 it->father = opa;
00219 }
00220 father->father = it;
00221
00222
if (father->left == it) {
00223
00224 DI temp = it->
right;
00225 it->right = father;
00226 father->left = temp;
00227
if (temp != NULL) temp->father = father;
00228 }
else {
00229
00230 assert(father->right == it);
00231 DI temp = it->
left;
00232 it->left = father;
00233 father->right = temp;
00234
if (temp != NULL) temp->father = father;
00235 }
00236 }
00237 }
00238
00239
template<
class K,
class I>
00240 inline void*
dictionary<K,I>::insert (
const K k,
const I i) {
00241
if (root == NULL) {
00242
00243 assert (
empty());
00244 root =
new _d_dic_item<K,I>(k,i);
00245 _size++;
00246
return (
void*)root;
00247 }
else {
00248
00249 assert (root != NULL);
00250 DI ins_pos = pos_finder(k);
00251 assert (ins_pos != NULL);
00252 DI it;
00253
switch (cmp_ptr(k, ins_pos->
key)) {
00254
case 0 :
00255
00256
change_inf(ins_pos, i);
00257 it = ins_pos;
00258
break;
00259
case -1 :
00260
00261 assert(ins_pos->left == NULL);
00262 it =
new _d_dic_item<K,I>(k,i);
00263 it->
father = ins_pos;
00264 ins_pos->left = it;
00265 _size++;
00266 rotation(it);
00267
break;
00268
case 1 :
00269
00270 assert(ins_pos->right == NULL);
00271 it =
new _d_dic_item<K,I>(k,i);
00272 it->
father = ins_pos;
00273 ins_pos->right = it;
00274 _size++;
00275 rotation(it);
00276
break;
00277
default : assert(
false);
break;
00278 }
00279
return (
void*)it;
00280 }
00281 }
00282
00283
template<
class K,
class I>
00284
inline _d_dic_item<K,I>*
dictionary<K,I>::pos_finder (
const K k)
const {
00285
00286
00287
00288
00289
00290
00291 assert (root != NULL);
00292 DI next = root;
00293 DI last;
00294
do {
00295 last = next;
00296
switch (cmp_ptr(k, next->key)) {
00297
case -1 : next = next->
left;
break;
00298
case 1 : next = next->right;
break;
00299
case 0 : next = NULL;
break;
00300
default : assert(
false);
break;
00301 }
00302 }
while (next != NULL);
00303 assert (last != NULL);
00304
return last;
00305 }
00306
00307
template<
class K,
class I>
00308 inline void*
dictionary<K,I>::next_item (
const void* it)
const {
00309
if (it==NULL)
return NULL;
00310
if (((DI)it)->right != NULL) {
00311
00312
return first_item( (
void*) ((DI)it)->right );
00313 }
else {
00314
00315 DI father = ((DI)it)->
father;
00316 DI last = ((DI)it);
00317
while (father != NULL) {
00318
if (father->
left == last) {
00319
00320
00321
return father;
00322 }
else {
00323
00324 last = father;
00325 father = father->
father;
00326 }
00327 }
00328
return NULL;
00329 }
00330 }
00331
00332
template<
class K,
class I>
00333 inline void dictionary<K,I>::del_item (
const void* it) {
00334 assert(it != NULL);
00335 DI left = ((DI)it)->
left;
00336 DI right = ((DI)it)->
right;
00337 DI* app_pos;
00338 DI dad;
00339
if ((DI)it == root) {
00340
00341
if ((left == NULL) & (right == NULL)) {
00342 root = NULL;
00343 app_pos = NULL;
00344 }
else {
00345
00346
00347
if ( (left==NULL) ?
false : ((right==NULL) ?
true : (left->
index < right->
index)) ) {
00348 assert (left!=NULL);
00349
00350 root = left;
00351
00352 left->
father = NULL;
00353
00354 app_pos = &(left->right);
00355 dad = left;
00356 left = left->
right;
00357 }
else {
00358 assert (right!=NULL);
00359 root = right;
00360 right->
father = NULL;
00361 app_pos = &(right->left);
00362 dad = right;
00363 right = right->
left;
00364 }
00365 }
00366 }
else {
00367
00368 dad = ((DI)it)->
father;
00369 assert (dad != NULL);
00370
00371 app_pos = (dad->
left == (DI)it) ? &(dad->
left) : &(dad->
right);
00372 }
00373
if (app_pos != NULL) {
00374
bool l_exists = (left != NULL);
00375
bool r_exists = (right != NULL);
00376
while ( l_exists & r_exists ) {
00377
if (left->
index < right->
index) {
00378 *app_pos = left;
00379 app_pos = &(left->right);
00380 left->
father = dad;
00381 dad = left;
00382 left = left->
right;
00383 l_exists = (left != NULL);
00384 }
else {
00385 *app_pos = right;
00386 app_pos = &(right->left);
00387 right->
father = dad;
00388 dad = right;
00389 right = right->
left;
00390 r_exists = (right != NULL);
00391 }
00392 }
00393
if (l_exists) {
00394 *app_pos = left;
00395 left->
father = dad;
00396 }
else if (r_exists) {
00397 *app_pos = right;
00398 right->
father = dad;
00399 }
else *app_pos = NULL;
00400 }
00401 _size--;
00402
delete (DI)it;
00403 }
00404
00405
template<
class K,
class I>
00406
inline void dictionary<K,I>::clear_helper (DI it) {
00407
if (it->l() != NULL)
00408 {
00409 DI l = (DI)(it->l());
00410 clear_helper( l );
00411 }
00412
if (it->r() != NULL)
00413 {
00414 DI r = (DI)(it->r());
00415 clear_helper( r );
00416 }
00417
delete it;
00418 _size--;
00419 }
00420
00422
00423
#endif
00424