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