C++复习之HashTable的简单实现
2016-07-29 11:52
441 查看
hashtable :本文中采用开链法( separate chaining )来处理 “ 冲突 ” ( collision ),而且 hashtable只存储唯一的元素,不存在重复。
class hashtable { public: // 构造函数, n 为想要构造的 hashtable 的 bucket 数量 hashtable(size_t n); ~hashtable(); // 插入元素。若元素不存在,插入成功返回 true ;若元素已存在则插入失败,返回 false bool insert(const int val); // 查找元素是否在表中出现 bool find(const int val); // 删除元素。若元素存在,删除成功返回 true ;若元素不存在则删除失败,返回 false bool erase(const int val); // 清除所有元素 void clear(); // 返回已有元素数目 size_t size(); private: // bucket 中的节点 struct hashtable_node { hashtable_node *next; int val; hashtable_node(int _val, hashtable_node *_next = NULL) : val(_val), next(_next) { } }; hashtable(const hashtable & h); // 暂时不允许拷贝和赋值 const hashtable & operator =(const hashtable & h); // hash 函数 size_t hash(unsigned long x); // 寻找大于等于 n 且最接近 n 的质数 unsigned long next_prime(unsigned long n); // bucket 向量表 vector<hashtable_node*> buckets; // 元素个数 size_t num_elements; }; hashtable::hashtable(size_t n) { // 将 bucket 数量设置为大于等于 n 且最接近 n 的质数 const size_t n_buckets = next_prime(n); buckets.reserve(n_buckets); buckets.insert(buckets.end(), n_buckets, NULL); num_elements = 0; }; hashtable::~hashtable() { // 清除所有链中的节点 clear(); } bool hashtable::insert(const int val) { // 不重复插入。已存在,返回 false if (find(val)) return false; // 调用 hash 函数获得 bucket 号 const size_t k = hash(val); // 将新节点直接插入到链表头部 hashtable_node * tmp = new hashtable_node(val); tmp->next = buckets[k]; buckets[k] = tmp; ++num_elements; // 插入成功 return true; } bool hashtable::find(const int val) { const size_t k = hash(val); hashtable_node *p = buckets[k]; // 在对应的 bucket 中查找 while (p != NULL) { if (p->val = val) return true; p = p->next; } return false; } bool hashtable::erase(const int val) { const size_t k = hash(val); hashtable_node *p = buckets[k]; hashtable_node *pre = NULL; // 找到该节点 while (p != NULL && p->val != val) { pre = p; p = p->next; } // 删除该节点 if (p == NULL) return false; if (pre == NULL) buckets[k] = p->next; // 删除第一个节点 else pre->next = p->next; delete p; return true; } void hashtable::clear() { // 清除所有链中的节点 for (int i = 0; i < buckets.size(); i++) { hashtable_node *p = buckets[i]; while (p != NULL) { hashtable_node *next = p->next; delete p; p = next; } } } size_t hashtable::size() { return num_elements; } size_t hashtable::hash(unsigned long x) { return x % buckets.size(); } unsigned long hashtable::next_prime(unsigned long n) { static const int num_primes = 28; static const unsigned long prime_list[num_primes] = { 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741, 3221225473ul, 4294967291ul }; // 寻找大于等于 n 且最接近 n 的质数 int i = 0; while (i < num_primes && prime_list[i] < n) i++; return i == num_primes ? prime_list[num_primes - 1] : prime_list[i]; } // 如果是含头结点的情况 bool hashtable::erase(const int val) { const size_t k = hash(val); hashtable_node *p = buckets[k]; hashtable_node *tmp = NULL; // 找到该节点 while (p->next != NULL && p->next->val != val) { p = p->next; } if (p->next == NULL) return false; // 删除该节点 tmp = p->next; p->next = tmp->next; delete tmp; return true; }
相关文章推荐
- [C++]数据结构:散列表HashTable的实现与简单应用
- c++复习一:复数运算的简单实现。
- 用C++实现简单的文件I/O操作
- 标准纯C++实现简单的词法分析器(一)
- C++中简单实现foreach循环
- 堆栈的简单C++实现
- JSP只用Hashtable和session实现购物车功能的简单实例
- C++ : 用proxy Class实现简单的二维数组。
- 大话设计模式之C++实现---简单工厂模式
- 数据结构复习:几种排序算法的C++实现和二叉树的相关算法实现
- 用C++实现简单的文件I/O操作
- 单链表赋值,定位,添加,(C++ ) 简单实现 未整理
- 标准纯C++实现简单的词法分析器(三)
- 标准纯C++实现简单的词法分析器(三)
- 实例学MFC(3)--超简单C++实现网络下载器
- 用C++实现简单的文件I/O操作
- 标准纯C++实现简单的词法分析器(二)
- 用C++实现简单的文件I/O操作(ifstream,ofstream)
- Java 一个简单Hashtable的实现
- 一个简单的多叉树C++实现