数据结构-散列表

数据结构-散列表

两个重要的问题:

  • 散列函数

  • 散列冲突

    • 散列函数的选择,使得尽可能少的发生散列冲突;
    • 标准的散列关键字是正整数,散列函数可能是整数除以散列表的大小取余;
    • 散列表的大小一般是素数,散列分布的更加均匀;
    • 如果关键字是字符串的话,散列函数可以是把字符串的所有ascII码加起来;

几个散列函数

int hashs1(const string & key, int tablesize){
    int hashval{0};
    for(char x:key){
        hashval+= x;
    }
    return hashval%tablesize;
}

int hashs2(const string& key, int tablesize){
    return (key[0]+27*key[1]+729*key[2])%tablesize;
}

int hashs3(const string& key, int tablesize){
    unsigned int hashval{0};
    for(char ch:key){
        hashval=37*hashval+ch; 
    }
    return hashval%tablesize;
}

如何解决散列冲突

分离链接法

将散列到同一个值的所有元素保存到一个链表中。一个典型的分离链接法哈希表

template<typename HashedObj>
class HashTable{

public:
    explicit HashTable(int size=101);

    bool contains(const HashedObj& x) const;
    void makeEmpty();

    bool insert(const HashedObj& x);
    bool insert(HashedObj&& x);
    bool remove(const HashedObj& x);

private:
    vector<list<HashedObj>> theList;
    int currentSize;
    void rehash();
    size_t myhash(const HashedObj& x);
};

template<typename HashedObj>
void HashTable<HashedObj>::makeEmpty(){
    for(auto& thisList:theList)
        thisList.clear();
} 

template <typename HashedObj>
bool HashTable<HashedObj>::contains(const HashedObj& x){
    auto & whichList = theList[myhash(x)];
    return find(begin(whichList), end(whichList), x) != end(whichList);
}

template<typename HashedObj>
bool HashTable<HashedObj>::remove(const HashedObj& x){

    auto& whichList = theList[myhash(x)];
    auto itr = find(begin(whichList), end(whichList),x);

    if(itr == end(whichList)) return false;

    whichList.erase(itr);
    --currentSize;
    return true;
}

template<typename HashedObj>
bool HashTable<HashedObj>::insert(const HashedObj& x){
    auto & whichList = theList[myhash(x)];
    if(find(begin(whichList),end(whichList),x) != end(whichList())) return false;
    whichList.push_back(x);

    if(++currentSize > theList.size())
        rehash();

    return true;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值