171 lines
3.8 KiB
C++
171 lines
3.8 KiB
C++
#include "Map.h"
|
|
#include "MapIterator.h"
|
|
#include <math.h>
|
|
#include <iostream>
|
|
|
|
Map::Map() {
|
|
//O(1)
|
|
this->_capacity=INITIAL_CAPACITY;
|
|
this->_size=0;
|
|
this->_elements=new TElem[this->_capacity];
|
|
this->_next=new int[this->_capacity];
|
|
for(int i=0;i<this->_capacity;i++){
|
|
this->_elements[i]=NULL_TELEM;
|
|
this->_next[i]=-1;
|
|
}
|
|
this->_nextFree=INITIAL_CAPACITY-1;
|
|
}
|
|
|
|
Map::~Map() {
|
|
//O(1)
|
|
delete[] this->_elements;
|
|
delete[] this->_next;
|
|
}
|
|
|
|
TValue Map::add(TKey c, TValue v){
|
|
// O(1) - amortized
|
|
if(this->_size>=this->_capacity*ALPHA)
|
|
this->_resize();
|
|
int hash=abs(c % this->_capacity);
|
|
while(this->_next[hash]!=-1 && this->_elements[hash].first!=c)
|
|
hash=this->_next[hash];
|
|
if(this->_elements[hash].first==c){
|
|
TValue oldValue=this->_elements[hash].second;
|
|
this->_elements[hash].second=v;
|
|
return oldValue;
|
|
}
|
|
this->_elements[this->_nextFree]=std::make_pair(c,v);
|
|
this->_next[hash]=this->_nextFree;
|
|
while(this->_elements[this->_nextFree]!=NULL_TELEM)
|
|
this->_nextFree--;
|
|
this->_size++;
|
|
return NULL_TVALUE;
|
|
}
|
|
|
|
TValue Map::search(TKey c) const{
|
|
// O(1) - amortized
|
|
int hash = abs(c % this->_capacity);
|
|
while (this->_next[hash] != -1 && this->_elements[hash].first != c)
|
|
hash = this->_next[hash];
|
|
if (this->_elements[hash].first == c)
|
|
return this->_elements[hash].second;
|
|
return NULL_TVALUE;
|
|
}
|
|
|
|
TValue Map::remove(TKey c){
|
|
//O(1) - amortized
|
|
int hash = abs(c % this->_capacity);
|
|
int prev = -1;
|
|
while (this->_next[hash] != -1 && this->_elements[hash].first != c) {
|
|
prev = hash;
|
|
hash = this->_next[hash];
|
|
}
|
|
if (this->_elements[hash].first == c) {
|
|
TValue oldValue = this->_elements[hash].second;
|
|
if (prev == -1) {
|
|
if(this->_next[hash]!=-1){
|
|
int remove = this->_next[hash];
|
|
this->_elements[hash] = this->_elements[this->_next[hash]];
|
|
this->_next[hash] = this->_next[this->_next[hash]];
|
|
this->_next[remove] = -1;
|
|
this->_elements[remove] = NULL_TELEM;
|
|
hash = remove;
|
|
}
|
|
else
|
|
this->_elements[hash] = NULL_TELEM;
|
|
}
|
|
else {
|
|
this->_next[prev] = this->_next[hash];
|
|
this->_elements[hash] = NULL_TELEM;
|
|
this->_next[hash] = -1;
|
|
}
|
|
if(hash>this->_nextFree)
|
|
this->_nextFree = hash;
|
|
this->_size--;
|
|
return oldValue;
|
|
}
|
|
return NULL_TVALUE;
|
|
}
|
|
|
|
|
|
int Map::size() const {
|
|
//O(1)
|
|
return this->_size;
|
|
}
|
|
|
|
bool Map::isEmpty() const{
|
|
//O(1)
|
|
return (this->_size==0);
|
|
}
|
|
|
|
MapIterator Map::iterator() const {
|
|
return MapIterator(*this);
|
|
}
|
|
|
|
void Map::_resize() {
|
|
//O(n)
|
|
int oldCapacity=this->_capacity;
|
|
this->_capacity*=2;
|
|
while(true){
|
|
bool ok=true;
|
|
for(int i=2;i<=sqrt(this->_capacity);i++)
|
|
if(this->_capacity%i==0){
|
|
ok=false;
|
|
break;
|
|
}
|
|
if(ok)
|
|
break;
|
|
this->_capacity++;
|
|
}
|
|
TElem* newElements=new TElem[this->_capacity];
|
|
int* newNext=new int[this->_capacity];
|
|
for(int i=0;i<this->_capacity;i++){
|
|
newElements[i]=NULL_TELEM;
|
|
newNext[i]=-1;
|
|
}
|
|
this->_nextFree=this->_capacity-1;
|
|
for(int i=0;i<oldCapacity;i++){
|
|
if(this->_elements[i]!=NULL_TELEM){
|
|
int hash=abs(this->_elements[i].first % this->_capacity);
|
|
while(newNext[hash]!=-1)
|
|
hash=this->_next[hash];
|
|
if(newElements[hash]==NULL_TELEM){
|
|
newElements[hash]=this->_elements[i];
|
|
newNext[hash]=-1;
|
|
}
|
|
else{
|
|
newElements[this->_nextFree]=this->_elements[i];
|
|
newNext[hash]=this->_nextFree;
|
|
while(newElements[this->_nextFree]!=NULL_TELEM)
|
|
this->_nextFree--;
|
|
}
|
|
|
|
}
|
|
}
|
|
delete[] this->_elements;
|
|
delete[] this->_next;
|
|
this->_elements=newElements;
|
|
this->_next=newNext;
|
|
|
|
|
|
}
|
|
|
|
int Map::getKeyRange() const{
|
|
//O(n)
|
|
MapIterator it = this->iterator();
|
|
if (!it.valid())
|
|
return -1;
|
|
int min = it.getCurrent().first;
|
|
int max = it.getCurrent().first;
|
|
while (it.valid()) {
|
|
if (it.getCurrent().first < min)
|
|
min = it.getCurrent().first;
|
|
if (it.getCurrent().first > max)
|
|
max = it.getCurrent().first;
|
|
it.next();
|
|
}
|
|
return max - min;
|
|
}
|
|
|
|
|