哈希表就是通过给定的key直接计算一个位置,然后直接去这个位置去寻找对应的数,因为位置是通过计算一次性得到的,而去对应的位置去找(因为内部使用数组进行存储),所以可以直接找到相应的位置,因此存储数据都是O(1)
HashMap.h
#ifndef HASHMAP_H
#define HASHMAP_H
#include <vector>
template<class Key, class Value>
class HashMap //哈希映射
{
public:
HashMap(int size = 101) : arr(size)
{
currentSize = 0;
}
void Put(const Key & k, const Value & v)
{
int pos = getArrVal(k);
arr[pos] = DataEntry(k,v);
++currentSize;
}
Value Get(const Key & k)
{
int pos = getArrVal(k);
//有可能pos处没放数,所以需要判断一下key
if(arr[pos].key == k)
return arr[pos].value;
else
return Value();
}
//通过key计算一个唯一的hashVal
unsigned int getHashVal(const Key & k) const
{
unsigned int hashVal = 0;
const char *keyp = reinterpret_cast<const char *>(&k);
for(size_t i=0; i<sizeof(Key); i++)
hashVal = 37 * hashVal + keyp[i];
return hashVal;
}
//将key映射到数组中,由于key很大,数组很小,所以需要进行映射
int getArrVal(const Key & k) const
{
unsigned hashVal = getHashVal(k);
hashVal %= arr.size();
return hashVal;
}
private:
struct DataEntry{
Key key;
Value value;
DataEntry(const Key & k = Key(),const Value & v = Value()):key(k),value(v){}
};
std::vector<DataEntry> arr;
int currentSize;
};
#endif
LinearMap.h
#ifndef LINEARMAP_H
#define LINEARMAP_H
#include <vector>
template<class Key, class Value>
class LinearMap
{
public:
LinearMap(int size = 101) : arr(size)
{
currentSize = 0;
}
void Put(const Key & k, const Value & v)
{
arr[currentSize] = DataEntry(k,v);
++currentSize;
}
Value Get(const Key & k)
{
//线性查找
for(size_t i=0; i<currentSize; ++i)
{
if(arr[i].key == k)
return arr[i].value;
}
return Value();
}
private:
struct DataEntry{
Key key;
Value value;
DataEntry(const Key & k = Key(),const Value & v = Value()):key(k),value(v){}
};
std::vector<DataEntry> arr;
int currentSize;
};
#endif
main.cpp
#include <iostream>
#include <map> //映射(也叫字典),二叉树映射,不是哈希映射
#include <string>
#include "LinearMap.h"
#include "HashMap.h"
using namespace std;
int main()
{
cout << "二叉树(红黑树)映射: " << endl;
map<string,int> m;
m["Bill"] = 98;
m["Tom"] = 67;
m["Mary"] = 100;
//...继续保存,保存了很多, 100万个,1000万个!
cout << m["Tom"] << endl;
//一个没用的,只仅学习的线性映射
LinearMap<string,int> lm;
lm.Put("Bill",99);
lm.Put("Tom",88);
lm.Put("Mary",77);
//继续put很多数据,100万个
cout << "LinearMap: " << lm.Get("Tom") << endl;
//我的哈希映射
cout << "我的哈希映射: " << endl;
HashMap<string,int> myHMap;
myHMap.Put("Bill",999);
myHMap.Put("Tom",888);
myHMap.Put("Mary",777);
cout << myHMap.Get("Tom") << endl;
system("pause");
return 0;
}