【习作】用二叉树处理溢出的哈希表
问题综述
这是我在学习数据结构时遇到的一个习题,要求使用二叉树处理存数冲突,而不是线性探查表使用的顺序向下存的方法。觉得有点意思,所以放上来。很显然,使用二叉树不会出现溢出的方法,而且也能享受二叉树的优秀搜索、插入、删除性能。
借物表
- 二叉树使用std::set
- hash函数采用std::hash
- 代码参考Sartaj Sahni的《数据结构、算法与应用》
基本思路
维护一个一维数组,类型为set*,用作hash table。如果出现冲突,用set处理。
代码
#include<iostream>#include<string>#include<set>usingnamespace std;classHashTable_BTree{//用二叉树实现溢出处理的哈希表set<pair<string,int>>** table;//表头hash<string> hash;//使用stl自带的hashint dSize;int divisor;//除数,决定树的数量public:HashTable_BTree(int theDivisor){divisor = theDivisor;dSize =0;table =newset<pair<string,int>>*[divisor];for(int i =0; i < divisor; i++){table[i]=newset<pair<string,int>>;table[i]->insert(pair<string,int>("ROOT",0));//将根节点占用了,原因是为了实现search方法}//初始化每个树}set<pair<string,int>>::iterator search(string key);const pair<string,int>* find(string key);void insert(pair<string,int>& ele);};set<pair<string,int>>::iterator HashTable_BTree::search(string key){int b = hash(key)%divisor;//知道应该放进第几个桶set<pair<string,int>>::iterator it = table[b]->begin();//获得树的迭代器while(it!=table[b]->end()){if(it->first == key){return it;//发现节点,返回指向该节点的迭代器}it++;}return it;//没有找到,返回指向根节点的迭代器}const pair<string,int>*HashTable_BTree::find(string key){set<pair<string,int>>::iterator it= search(key);//这时,由search()方法可以看出,如果it指向根,说明没找到//如果it指向非根,说明找到了int b = hash(key)% divisor;if(it->first ==string("ROOT"))returnnullptr;const pair<string,int>* answear =&it.operator*();//这里有点混淆,可以指出迭代器的操作符*是重载的,不是通常的取值操作,所以&*it是有效的,为了方便辨认,我写成左式这样return answear;}voidHashTable_BTree::insert(pair<string,int>& ele){//插入操作int b = hash(ele.first)% divisor;table[b]->insert(ele);}int main(){//测试程序HashTable_BTree a(10);a.insert(pair<string,int>("Hello",64));if(a.find(string("Hello"))!=nullptr)cout <<"found one!"<< endl;system("pause");}
改进
很显然,search方法用的是遍历,没有充分享受set的优秀性能,但是因为set存的是指针pair*,需要自己写一个大小比较获得最优性能
浙公网安备 33010602011771号