C++:哈希
1.基本概念
哈希一般用来快速查找,通过hash函数将输入的键值(key)映射到某一个地址,然后就可以获得该地址的内容。
同样,如果要储存一对值(键值和数据),则也是通过hash函数获得地址来存入。见图例:
不过这其中会出现一些问题,最常见的是出现冲突。就是输入不同的key,经过hash之后得到同样的值,也就是在同一个地址要储存不同的data,
例如使用上图的hash,输入的key为1和11得到的地址都是1,则这种就是出现了冲突。
解决这种冲突的方法有多种,比如线性探测法,折叠法,链表法等等。
2.实例
下面是一个基于C++的简单的模板类,使用链表法来解决冲突。该hash类的数据结构为:
struct data { size_t key; map_t content; bool isEmpty; data * next; data() :isEmpty(true), next(nullptr){} };
程序:
template<typename map_t> class MyHash { public: MyHash() :size(1000) { store = new data[size]; } MyHash(size_t s) :size(s) { store = new data[size]; } ~MyHash() { delete[]store; } public: bool insert(size_t key, map_t val); bool find(size_t key, map_t & val); bool erase(size_t key); void print(); private: size_t size; struct data { size_t key; map_t content; bool isEmpty; data * next; data() :isEmpty(true), next(nullptr){} }; data * store; size_t hash(size_t key); }; template<typename map_t> bool MyHash<map_t>::insert(size_t key, map_t val) { size_t t_k = hash(key); if (t_k >= size || t_k < 0) return false; if (!store[t_k].isEmpty) { data * temp_ptr = & store[t_k]; while (temp_ptr->next!=nullptr) { temp_ptr = temp_ptr->next; if (temp_ptr->key == key) { temp_ptr->content = val; return true; } } data *new_ = new data; new_->key = key; new_->content = val; new_->isEmpty = false; new_->next = nullptr; temp_ptr->next = new_; return true; } data* new_ = new data; new_->key = key; new_->content = val; new_->isEmpty = false; new_->next = nullptr; store[t_k].next = new_; store[t_k].isEmpty = false; return true; } template<typename map_t> bool MyHash<map_t>::find(size_t key, map_t& val) { size_t t_k = hash(key); if (t_k >= size || t_k < 0) return false; data * temp_ptr = &store[t_k]; while (temp_ptr->next != nullptr) { temp_ptr = temp_ptr->next; if (temp_ptr->key == key) { val = temp_ptr->content; return true; } } return false; } template<typename map_t> bool MyHash<map_t>::erase(size_t key) { size_t t_k = hash(key); if (t_k >= size || t_k < 0 || store[t_k].isEmpty) return false; data * temp_ptr = &store[t_k]; data * temp_ptr_ = &store[t_k]; while (temp_ptr->next!=nullptr) { temp_ptr_ = temp_ptr; temp_ptr = temp_ptr->next; if (temp_ptr->key == key) { temp_ptr_->next = temp_ptr->next; delete temp_ptr; return true; } } return false; } template<typename map_t> void MyHash<map_t>::print() { for (int i = 0; i < size; ++i) { if (!store[i].isEmpty) { cout << i << " : "; data * temp_ptr = &store[i]; while (temp_ptr->next != nullptr) { temp_ptr = temp_ptr->next; cout << " - " << temp_ptr->content; } cout << endl; } } } template<typename map_t> size_t MyHash<map_t>::hash(size_t key) { return key%size; }
------------ 转载请注明出处 ------------