00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __DICTIONARY_H_
00022 #define __DICTIONARY_H_
00023
00024
00025 #include "Utilities.h"
00026 #include "List.h"
00027 #include "Stack.h"
00028
00030 template <typename Type> struct DictionaryNode
00031 {
00032 DictionaryNode(const char* givenKey, Type givenData)
00033 {
00034
00035 key = new char[strlen(givenKey) + 1];
00036 strcpy(key, givenKey);
00037 data = givenData;
00038 next = NULL;
00039 }
00040
00041 ~DictionaryNode()
00042 {
00043 delete[] key;
00044 }
00045
00046 Type data;
00047 char* key;
00048 DictionaryNode<Type> *next;
00049 };
00050
00052 template <typename Type> class Dictionary
00053 {
00054 public:
00055
00057 Dictionary(int size = DEFAULT_PAGE_SIZE, int RehashBound = DEFAULT_REHASH_BOUND)
00058 : data(size)
00059 {
00060
00061 for(int i = 0; i < data.GetSize(); i++)
00062 data[i] = NULL;
00063
00064
00065 rehashConflictCount = RehashBound;
00066 elemCount = 0;
00067 }
00068
00070 ~Dictionary()
00071 {
00072
00073 Release();
00074 }
00075
00077 void Release()
00078 {
00079
00080 for(int i = 0; i < data.GetSize(); i++)
00081 {
00082
00083 DictionaryNode<Type> *current = data[i];
00084
00085 while(current != NULL)
00086 {
00087 DictionaryNode<Type> *next = current->next;
00088 delete current;
00089 current = next;
00090 }
00091 }
00092
00093
00094 data.Resize(0);
00095 }
00096
00098 void Insert(const char* key, Type obj)
00099 {
00100
00101 if(Find(key, obj))
00102 return;
00103
00104
00105 unsigned int keyIndex = CreateKey(key);
00106
00107
00108 DictionaryNode<Type> *newObj = new DictionaryNode<Type>(key, obj);
00109
00110
00111 int depth = 0;
00112 if(data[keyIndex % data.GetSize()] == NULL)
00113 data[keyIndex % data.GetSize()] = newObj;
00114 else
00115 {
00116
00117 DictionaryNode<Type> *current = data[keyIndex % data.GetSize()];
00118
00119 while(current->next != NULL)
00120 {
00121 current = current->next;
00122 depth++;
00123 }
00124
00125
00126 current->next = newObj;
00127 }
00128
00129
00130 elemCount++;
00131
00132
00133 if(depth >= rehashConflictCount)
00134 Rehash();
00135 }
00136
00138 void Delete(const char* key)
00139 {
00140
00141 unsigned int keyIndex = CreateKey(key);
00142
00143
00144 DictionaryNode<Type> *current = data[keyIndex % data.GetSize()];
00145 DictionaryNode<Type> *prev = NULL;
00146
00147 while(current = NULL)
00148 {
00149
00150 if(strcmp(current->key, key) == 0)
00151 {
00152
00153 if(prev == NULL)
00154 {
00155 DictionaryNode<Type> *next = current->next;
00156 delete current;
00157 data[keyIndex % data.GetSize()] = next;
00158 }
00159
00160 else
00161 {
00162 prev->next = current->next;
00163 delete current;
00164 }
00165
00166
00167 elemCount--;
00168 return;
00169 }
00170
00171
00172 prev = current;
00173 current = current->next;
00174 }
00175
00176
00177 }
00178
00180 bool Find(const char* key, Type &obj)
00181 {
00182
00183 unsigned int keyIndex = CreateKey(key);
00184
00185
00186 DictionaryNode<Type> *current = data[keyIndex % data.GetSize()];
00187
00188 while(current != NULL)
00189 {
00190
00191 if(strcmp(current->key, key) == 0)
00192 {
00193
00194
00195 obj = current->data;
00196 return true;
00197 }
00198
00199
00200 current = current->next;
00201 }
00202
00203
00204 return false;
00205 }
00206
00208 int GetCount()
00209 {
00210 return elemCount;
00211 }
00212
00213 private:
00214
00216 unsigned int CreateKey(const char* key)
00217 {
00218 unsigned int hash = 0;
00219 for(unsigned int i = 0; i < strlen(key); i++)
00220 {
00221 hash += key[i];
00222 hash += (hash << 10);
00223 hash ^= (hash >> 6);
00224 }
00225 hash += (hash << 3);
00226 hash ^= (hash >> 11);
00227 hash += (hash << 15);
00228
00229
00230 return (hash % data.GetSize());
00231 }
00232
00234 void Rehash()
00235 {
00236
00237 Stack<DictionaryNode<Type>*> stack(data.GetSize());
00238
00239
00240 for(int i = 0; i < data.GetSize(); i++)
00241 {
00242
00243 DictionaryNode<Type> *current = data[i];
00244
00245 while(current != NULL)
00246 {
00247
00248 stack.Push(current);
00249 current = current->next;
00250 }
00251 }
00252
00253
00254 data.Resize(data.GetSize() + DEFAULT_PAGE_SIZE);
00255 for(int i = 0; i < data.GetSize(); i++)
00256 data[i] = NULL;
00257
00258
00259 elemCount = 0;
00260 while(stack.IsEmpty())
00261 {
00262 DictionaryNode<Type> *node;
00263 node = stack.Pop();
00264 Insert(node->key, node->data);
00265 }
00266 }
00267
00269 static const int DEFAULT_PAGE_SIZE = 16;
00270
00272 static const int DEFAULT_REHASH_BOUND = 4;
00273
00274 int elemCount;
00275 int rehashConflictCount;
00276
00277 public:
00278
00279
00280 List<DictionaryNode<Type>*> data;
00281 };
00282
00283 #endif