哈希集合

7 篇文章 0 订阅



                                                                                                                                                                                                                                  ---------来自STL源码剖析


#include <iostream>
#include <vector>
#include <cstdio>
#include <list>
using namespace std;

const int hash_prime_num = 15;
const unsigned int _stl_prime[] = {
    2,        5,        11,        23,        53,
    97,     193,     389,     769,     1543,
    3079,     6151,     12289,     24593,     49157
};//此处定义出15个素数,以便于用开链法建立哈希表

template<class T, class H, class E, class type_value>
//四个模板类型,分为代表集合元素类型,哈希仿函数,相等判定仿函数,底层容器实现方式(开链法链的实现方式)
struct Hash_set{
    typedef typename vector<type_value>::iterator first_it;
    typedef typename type_value::iterator second_it;
    typedef typename vector<type_value>::const_iterator first_ct;
    typedef typename type_value::const_iterator second_ct;
    typedef vector<type_value>* pointer;
    typedef T type;

    size_t count, table_size;//前者是集合元素数目,后者是哈希表大小
    vector<type_value> v;//哈希表,用vector实现
    H hash;//哈希仿函数
    E equal;//相等判定仿函数
    size_t find_prime(int num){//查找下一个更大的素数
        for(int i = 0; i < hash_prime_num; i++){
            if(_stl_prime[i] > num) return _stl_prime[i];
        }
    }
    bool add(const T& data){//把一个元素加入哈希表,元素不可以重复
        size_t index = hash(data) % table_size;
        type_value &buf = v[index];
        for(second_it it = buf.begin(); it != buf.end(); ++it)
            if(equal(data, *it)) return false;
        v[index].push_back(data);
        return true;
    }
public:

    struct iterator{//依旧是一个很简陋的迭代器,只重载了前++运算符
        first_it itx;
        second_it ity;
        pointer v;
        iterator():itx(first_it()), ity(second_it()), v(NULL){}
        iterator(const iterator& buf){itx = buf.itx, ity = buf.ity, v = buf.v;}
        iterator(const first_it& _x, const second_it& _y, pointer _v):itx(_x), ity(_y), v(_v){}
        T& operator*(){ return *ity;}
        bool operator ==(const iterator& R){return itx == R.itx && ity == R.ity;}
        bool operator != (const iterator& R){return !(itx == R.itx && ity == R.ity);}
        iterator& operator ++(){
            if(++ity != itx->end()) { return *this;}
            for(++itx; itx != v->end(); ++itx) if(itx->size()){
                ity = itx->begin();
                return *this;
            }
            ity = second_it();
            return *this;
        }
    };
    
    iterator begin(){//返回首迭代器
        for(first_it it = v.begin(); it != v.end(); ++it) if(it->size())
            return iterator(it, it->begin(), &v);
    }
    iterator begin()const{
        for(first_ct it = v.begin(); it != v.end(); ++it) if(it->size())
            return iterator(it, it->begin(), &v);
    }
    iterator end(){ return iterator(v.end(), second_it(), NULL);}//返回最后一个元素的下一个迭代器
    iterator end()const{ return iterator(v.end(), second_ct(), NULL);}
    Hash_set(){table_size = 2, count = 0, v.resize(table_size);}
    
    size_t size()const{ return count;}//集合元素数目
    size_t hash_size()const{ return table_size;}//    是哈希表大小
    Hash_set& operator = (const Hash_set& R){v = R.v;}//重载赋值运算符
    
    void insert(const T& data){//插入一个元素
        if(count == table_size/2){
            type_value buf;
            for(first_it itx = v.begin(); itx != v.end(); ++itx)
                for(second_it ity = itx->begin(); ity != itx->end(); ++ity)
                    buf.push_back(*ity);
            table_size = find_prime(table_size);
            v.clear();
            v.resize(table_size);
            for(second_it it = buf.begin(); it != buf.end(); ++it) add(*it);
        }
        count += add(data);
    }
    bool find(const T& data){//查找一个元素是否存在
        size_t index = (hash(data)) % table_size;
        type_value &buf = v[index];
        for( second_it it = buf.begin(); it != buf.end(); ++it)
            if(equal(data, *it)) return true;    
        return false;
    }
    bool find(const T& data)const{
        size_t index = (hash(data)) % table_size;
        type_value &buf = v[index];
        for(second_ct it = buf.begin(); it != buf.end(); ++it)
            if(equal(data, *it)) return true;    
        return false;
    }
    void erase(const T& data){//删除一个元素
        size_t index = (hash(data)) % table_size;
        type_value &buf = v[index];
        for(second_it it = buf.begin(); it != buf.end(); ++it)
            if(equal(data, *it)){
                buf.erase(it);
                break;
            }
    }

};

struct hasher{
    size_t operator()(int x)const{
        return x;
    }
};
struct equaler{
    bool operator()(int a, int b)const{
        return a == b;
    }
};

int main(int argc, char** argv) {
    Hash_set<int, hasher, equaler, list<int> > st, R;
    for(int i = 0; i < 10; i++) st.insert(i*2-3);
    for(int i = 0; i < 10; i++) cout << st.find(i) << " ";
    puts("");
    for(Hash_set<int, hasher, equaler, list<int> >::iterator it = st.begin(); it != st.end(); ++it){
        cout << *it << " " << endl;
    }
    puts("----------------");
    R = st;
    for(Hash_set<int, hasher, equaler, list<int> >::iterator it = R.begin(); it != R.end(); ++it){
        cout << *it << " " << endl;
    }
    
    cout << st.size() << " " << st.hash_size() << endl;
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值