您的位置:首页 > 理论基础 > 数据结构算法

C++数据结构 之 哈希表(散列表)_Hash Table

2016-08-12 10:51 751 查看

C++数据结构 之 哈希表(散列表)_Hash Table

源代码只包含头文件

注:需要C++11的支持

一、哈希表

哈希表是一种高效的数据结构,能在平均时间复杂度O(n)的情况下存储与查询。它是根据关健值(key)进行访问的。存在一函数,当key传入函数之后,函数输出一个独一无二的值val,函数叫哈希函数。当给定所存储容器V大小为m时,那么输入元素所在的位置就是val % m。

当输入很多元素之后, 同一位置下就可能会存入多个元素,因而产生冲突(collision),那么这时候就需要用链接(chaining)来解决问题:使用链表将同一位置下的元素链起来。

支持的操作:

1、insert 插入元素

2、erase 删除元素

3、search 搜索元素

示意图:



二、源代码:

#ifndef HASH_TABLE_H
#define HASH_TABLE_H

#include <vector>
#include <list>
#include <utility>
#include <stdexcept>
#include <algorithm>
#include <functional>

using std::vector;
using std::list;
using std::hash;
using std::pair;

template<typename T>
class Sgl_HashTable {
typedef typename list<T>::iterator iterator;
public:
Sgl_HashTable() { resize(); }
Sgl_HashTable(const size_t &temp_bucket) {
bucket = temp_bucket;
elem.resize(bucket);
}
~Sgl_HashTable() = default;

size_t Hash_Val(const T &x) {
return hash<T>()(x) % bucket;
}

void insert(const T &x) {
auto Hval = Hash_Val(x);
elem[Hval].push_back(x);
}

pair<size_t, iterator> search(const T &x) {
auto Hval = Hash_Val(x);
auto pos = find(elem[Hval].begin(), elem[Hval].end(), x);
try {
if (pos == elem[Hval].end()) {
throw runtime_error("The element was not found.");
}
}
catch (runtime_error &err) {
cout << err.what() << endl;
}

return std::make_pair(Hval, pos);
}

void erase_one(const T &x) {
auto p = search(x);
if (p.second != elem[p.first].end()) {
elem[p.first].erase(p.second);
}
}

void erase(const T &x) {
auto p = search(x);
auto pos = p.second;
if (pos != elem[p.first].end()) {
while (pos != elem[p.first].end() && *pos == x) {
pos = elem[p.first].erase(pos);
}
}
}

private:
vector<list<T>> elem;
size_t bucket = 100;
void resize() { elem.resize(bucket); }
};

template<typename key, typename T>
class Dbl_HashTable {
typedef typename list<pair<key, T>>::iterator iterator;
public:
Dbl_HashTable() { resize(); }
Dbl_HashTable(const key &temp_bucket) {
bucket = temp_bucket;
elem.resize(bucket);
}

size_t Hash_Val(const key &x) {
return hash<T>()(x) % bucket;
}

void insert(const key &x1, const T &x2) {
auto Hval = Hash_Val(x1);
elem[Hval].push_back(std::make_pair(x1, x2));
}

pair<size_t, iterator> search(const key &x) {
auto Hval = Hash_Val(x);
auto pos = find_if(elem[Hval].begin(), elem[Hval].end(), [&](pair<key, T> temp_p)->bool {
return temp_p.first == x;
});
try {
if (pos == elem[Hval].end()) {
throw runtime_error("The element was not found.");
}
}
catch (runtime_error &err) {
cout << err.what() << endl;
}

return std::make_pair(Hval, pos);
}

void erase_one(const key &x) {
auto p = search(x);
if (p.second != elem[p.first].end()) {
elem[p.first].erase(p.second);
}
}

void erase(const key &x) {
auto p = search(x);
auto pos = p.second;
if (pos != elem[p.first].end()) {
while (pos != elem[p.first].end() && pos->first == x) {
pos = elem[p.first].erase(pos);
}
}
}

private:
vector<list<pair<key, T>>> elem;
size_t bucket = 100;
void resize() { elem.resize(bucket); }
};

#endif // !HASH_TABLE_H


注解:支持两种元素类型,一种是单元素(key),一种是双元素(key, T),分别对应于Sgl_HashTable和Dbl_HashTable。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: