在C++中,可以使用哈希表(通常通过链表法解决冲突)封装unordered_set和unordered_map。以下是核心实现步骤和代码示例:
1. 哈希表基础结构
哈希节点模板(支持键值对):
template <typename K, typename V>
struct HashNode {
K key;
V value;
HashNode* next;
HashNode(const K& k, const V& v) : key(k), value(v), next(nullptr) {}
};
桶数组与哈希函数:
template <typename K>
struct DefaultHashFunc {
size_t operator()(const K& key) const {
return std::hash<K>()(key);
}
};
2. 封装unordered_set
核心结构:
template <typename K, typename Hash = DefaultHashFunc<K>>
class UnorderedSet {
private:
std::vector<HashNode<K, K>*> buckets; // 存储节点指针
size_t bucket_count = 10; // 初始桶数量
Hash hash_func; // 哈希函数对象
// 获取桶索引
size_t get_bucket_index(const K& key) const {
return hash_func(key) % bucket_count;
}
public:
// 插入元素
void insert(const K& key) {
size_t index = get_bucket_index(key);
HashNode<K, K>* node = buckets[index];
while (node) {
if (node->key == key) return; // 已存在
node = node->next;
}
auto* new_node = new HashNode<K, K>(key, key);
new_node->next = buckets[index];
buckets[index] = new_node;
}
};
3. 封装unordered_map
修改节点与接口:
template <typename K, typename V, typename Hash = DefaultHashFunc<K>>
class UnorderedMap {
private:
std::vector<HashNode<K, V>*> buckets;
// … 其他与set类似
public:
// 插入键值对
void insert(const K& key, const V& value) {
size_t index = get_bucket_index(key);
HashNode<K, V>* node = buckets[index];
while (node) {
if (node->key == key) {
node->value = value; // 更新值
return;
}
node = node->next;
}
auto* new_node = new HashNode<K, V>(key, value);
new_node->next = buckets[index];
buckets[index] = new_node;
}
// 重载[]运算符
V& operator[](const K& key) {
size_t index = get_bucket_index(key);
HashNode<K, V>* node = buckets[index];
while (node) {
if (node->key == key) return node->value;
node = node->next;
}
// 若不存在,插入默认值
insert(key, V());
return buckets[index]->value;
}
};
http://my.tv.sohu.com/us/442288713/698727005.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzAwNS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726934.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjkzNC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726853.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjg1My5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727016.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzAxNi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726938.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjkzOC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726955.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjk1NS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727038.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzAzOC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726880.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjg4MC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727053.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzA1My5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726884.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjg4NC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727062.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzA2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726887.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjg4Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726997.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjk5Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727302.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzMwMi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727304.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzMwNC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698726896.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNjg5Ni5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727305.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzMwNS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727077.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzA3Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727080.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzA4MC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727148.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzE0OC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727153.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzE1My5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727155.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzE1NS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727336.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzMzNi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727347.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzM0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727179.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzE3OS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727186.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzE4Ni5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727365.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzM2NS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727422.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQyMi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727425.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQyNS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727429.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQyOS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727434.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQzNC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727444.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQ0NC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727393.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzM5My5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727292.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzI5Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727457.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQ1Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727702.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzcwMi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727534.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzUzNC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727616.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzYxNi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727542.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzU0Mi5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727619.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzYxOS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727553.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzU1My5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727473.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzQ3My5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727727.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzcyNy5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727739.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzczOS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727740.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzc0MC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727579.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzU3OS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727655.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzY1NS5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727584.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzU4NC5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727757.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzc1Ny5zaHRtbA==.html http://my.tv.sohu.com/us/442288713/698727823.shtml https://tv.sohu.com/v/dXMvNDQyMjg4NzEzLzY5ODcyNzgyMy5zaHRtbA==.html
4. 迭代器实现(以unordered_map为例)
迭代器类:
template <typename K, typename V>
class UnorderedMapIterator {
private:
std::vector<HashNode<K, V>*>& buckets;
size_t bucket_index;
HashNode<K, V>* current;
// 找到下一个非空桶
void find_next() {
while (bucket_index < buckets.size() && !current) {
bucket_index++;
if (bucket_index < buckets.size()) current = buckets[bucket_index];
}
}
public:
UnorderedMapIterator(std::vector<HashNode<K, V>*>& b, size_t idx, HashNode<K, V>* node)
: buckets(b), bucket_index(idx), current(node) {
find_next();
}
// 重载++运算符
UnorderedMapIterator& operator++() {
if (current) current = current->next;
if (!current) {
bucket_index++;
find_next();
}
return *this;
}
// 重载*运算符
std::pair<K, V> operator*() const {
return {current->key, current->value};
}
};
5. 完整示例调用
int main() {
UnorderedMap<std::string, int> map;
map.insert("one", 1);
map["two"] = 2; // 使用[]插入
// 遍历输出
for (auto it = map.begin(); it != map.end(); ++it) {
std::cout << (*it).first << ": " << (*it).second << std::endl;
}
return 0;
}
关键优化方向:
通过以上结构,可灵活扩展为类似STL的哈希容器实现。
