【习作】用二叉树处理溢出的哈希表

 

问题综述

这是我在学习数据结构时遇到的一个习题,要求使用二叉树处理存数冲突,而不是线性探查表使用的顺序向下存的方法。觉得有点意思,所以放上来。很显然,使用二叉树不会出现溢出的方法,而且也能享受二叉树的优秀搜索、插入、删除性能。

 

借物表

  1. 二叉树使用std::set
  2. hash函数采用std::hash
  3. 代码参考Sartaj Sahni的《数据结构、算法与应用》
 

基本思路

维护一个一维数组,类型为set*,用作hash table。如果出现冲突,用set处理。

 

代码

 
  1. #include<iostream>
  2. #include<string>
  3. #include<set>
  4. usingnamespace std;
  5. classHashTable_BTree
  6. {
  7. //用二叉树实现溢出处理的哈希表
  8. set<pair<string,int>>** table;//表头
  9. hash<string> hash;//使用stl自带的hash
  10. int dSize;
  11. int divisor;//除数,决定树的数量
  12. public:
  13. HashTable_BTree(int theDivisor)
  14. {
  15. divisor = theDivisor;
  16. dSize =0;
  17. table =newset<pair<string,int>>*[divisor];
  18. for(int i =0; i < divisor; i++)
  19. {
  20. table[i]=newset<pair<string,int>>;
  21. table[i]->insert(pair<string,int>("ROOT",0));//将根节点占用了,原因是为了实现search方法
  22. }//初始化每个树
  23. }
  24. set<pair<string,int>>::iterator search(string key);
  25. const pair<string,int>* find(string key);
  26. void insert(pair<string,int>& ele);
  27. };
  28. set<pair<string,int>>::iterator HashTable_BTree::search(string key)
  29. {
  30. int b = hash(key)%divisor;//知道应该放进第几个桶
  31. set<pair<string,int>>::iterator it = table[b]->begin();//获得树的迭代器
  32. while(it!=table[b]->end())
  33. {
  34. if(it->first == key)
  35. {
  36. return it;//发现节点,返回指向该节点的迭代器
  37. }
  38. it++;
  39. }
  40. return it;//没有找到,返回指向根节点的迭代器
  41. }
  42. const pair<string,int>*HashTable_BTree::find(string key)
  43. {
  44. set<pair<string,int>>::iterator it= search(key);
  45. //这时,由search()方法可以看出,如果it指向根,说明没找到
  46. //如果it指向非根,说明找到了
  47. int b = hash(key)% divisor;
  48. if(it->first ==string("ROOT"))returnnullptr;
  49. const pair<string,int>* answear =&it.operator*();//这里有点混淆,可以指出迭代器的操作符*是重载的,不是通常的取值操作,所以&*it是有效的,为了方便辨认,我写成左式这样
  50. return answear;
  51. }
  52. voidHashTable_BTree::insert(pair<string,int>& ele)
  53. {
  54. //插入操作
  55. int b = hash(ele.first)% divisor;
  56. table[b]->insert(ele);
  57. }
  58. int main()
  59. {//测试程序
  60. HashTable_BTree a(10);
  61. a.insert(pair<string,int>("Hello",64));
  62. if(a.find(string("Hello"))!=nullptr)
  63. cout <<"found one!"<< endl;
  64. system("pause");
  65. }
 

改进

很显然,search方法用的是遍历,没有充分享受set的优秀性能,但是因为set存的是指针pair*,需要自己写一个大小比较获得最优性能

posted @ 2017-12-28 23:28  我也想学编程  阅读(245)  评论(0编辑  收藏  举报