hashtables之哈希桶法

#pragma once
#include<iostream>
#include<vector>
#include<string>

using namespace std;


template<class K,class V>
struct HashTablesNode
{
    K _key;
    V _value;
    struct HashTablesNode* next;
    HashTablesNode(const K& key, const V& value)
        : _key(key)
        , _value(value)
        , next(NULL)
    {}
};

static size_t BKDRHash(const char * str)
{
    unsigned int seed = 131; // 31 131 1313 13131 131313
    unsigned int hash = 0;
    while (*str)
    {
        hash = hash * seed + (*str++);
    }
    return (hash & 0x7FFFFFFF);
}


//为string定制的仿函数
struct __HashFuncS
{
    size_t operator()(const string& str)
    {
        return BKDRHash(str.c_str());
    }
};

//对 int型
struct __HashFuncInt
{
    size_t operator()(const int& key)
    {
        return key;
    }
};

template<class K, class V, class H = __HashFuncInt >
class HashTables
{
    typedef HashTablesNode<K,V> Node;
public:
    HashTables()
    {}
    HashTables(size_t _size) 
    {
        _table.resize(GetNextCapacity(size));
    }

    void print()
    {
        for (size_t i = 0; i < _table.size();++i)
        {
            printf("_hashtable[%d]->", i);
            Node* pcur = _table[i];
            while (pcur)
            {
                cout << pcur->_key << " :"<<pcur->_value<<"  ";
                pcur = pcur->next;
            }
            cout << endl;
        }
    }

    bool Find(const K& key)
    {
        int index = _HashFunc(key,_table.size());
        Node* pcur = _table[index];
        while (pcur)
        {
            if (pcur->_key == key)
                return true;
            pcur = pcur->next;
        }
        return false;
    }

    bool Insert(const K& key, const V& value)
    {
        CheckCapacity();
        if (Find(key))
            return false;
        int index = _HashFunc(key,_table.size());
        Node* tmp = new Node(key, value);
        tmp->next = _table[index];
        _table[index] = tmp;

        size++;
        return true;
    }

    bool Remove(const K& key)
    {
        size_t index = _HashFunc(key, _table.size());
        Node* pcur = _table[index];
        if (pcur->_key == key)
            _table[index] = pcur->next;
        else
        {
            while (pcur)
            {
                Node* prev = pcur;
                pcur = pcur->next;
                if (pcur->_key == key)
                {
                    prev->next = pcur->next;
                }
            }
            if (pcur == NULL)
                return false;
        }
        delete pcur;
        size--;
        return true;
    }
private:
    size_t GetNextCapacity(size_t size)
    {
        const int _PrimeSize = 28;
        static const unsigned long _PrimeList[_PrimeSize] =
        {
            53ul, 97ul, 193ul, 389ul, 769ul,
            1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
            49157ul, 98317ul, 196613ul, 393241ul,
            786433ul,
            1572869ul, 3145739ul, 6291469ul, 12582917ul,
            25165843ul,
            50331653ul, 100663319ul, 201326611ul, 402653189ul,
            805306457ul,
            1610612741ul, 3221225473ul, 4294967291ul
        };

        for (size_t i = 0; i < _PrimeSize; ++i)
        {
            if (size < _PrimeList[i])
                return _PrimeList[i];
        }
        return _PrimeList[_PrimeSize];
    }

    size_t _HashFunc(const K& key, size_t size)//除留余数法
    {
        return H()(key) % size;
    }

    void CheckCapacity()
    {
        if (size == _table.size())//负载因子达到1.0
        {
            //_table.resize(size * 2 + 3);
            vector<Node*> newtable;
            newtable.resize(GetNextCapacity(size));
            for (size_t i = 0; i < _table.size(); ++i)
            {
                Node* pcur = _table[i];
                while (pcur)
                {
                    Node* pnext = pcur->next;
                    //
                    int index = _HashFunc(pcur->_key, newtable.size());
                    pcur->next = newtable[index];
                    newtable[index] = pcur;

                    _table[i] = pnext;
                    pcur = _table[i];
                }
            }
            swap(newtable, _table);
        }
    }
private:
    vector<Node*> _table;
    size_t size;
};

用了素数表来配合除留余数法来减少冲突,用了哈希桶来处理哈希碰撞;
哈希表每个元素都是一个指针,指向一个单链表的第一个节点。插入数据就是往对应的key下面挂节点,查找的时候直接定位到对应的哈希表的位置,然后遍历单链表查找。对于这个单链表也可以其他方式来组织,如红黑树,让哈希表里面保存红黑树的根节点指针即可;
哈希桶的做法,相对于二次探测和线性探测,减少了前面数据对本次插入数据的影响。时间复杂度实际上通过优化可以达到0(1);缺点是比较浪费空间;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PHP 中可以使用函数 `array_keys()` 来查找所有哈希表的键,例如: ``` $hashtable = array('a' => 1, 'b' => 2, 'c' => 3); $keys = array_keys($hashtable); print_r($keys); ``` 输出结果为: ``` Array ( [0] => a [1] => b [2] => c ) ``` 如果要查找所有哈希表的值,可以使用函数 `array_values()`,例如: ``` $hashtable = array('a' => 1, 'b' => 2, 'c' => 3); $values = array_values($hashtable); print_r($values); ``` 输出结果为: ``` Array ( [0] => 1 [1] => 2 [2] => 3 ) ``` 如果要查找所有哈希表的键和值,可以使用 `foreach` 语句遍历哈希表,例如: ``` $hashtable = array('a' => 1, 'b' => 2, 'c' => 3); foreach ($hashtable as $key => $value) { echo "$key => $value\n"; } ``` 输出结果为: ``` a => 1 b => 2 c => 3 ``` ### 回答2: 要查找PHP中所有的哈希表,可以使用遍历和递归的方来实现。在PHP中,哈希表可以通过数组表示。 首先,我们可以使用全局变量$GLOBAL来获取当前脚本中的所有变量。然后,使用foreach循环遍历$GLOBAL数组中的每个元素,判断每个元素是否为数组。 如果元素是数组,那么就可以确定它是一个哈希表。我们可以再次使用foreach循环遍历这个数组,以获取哈希表中的键和对应的值。 下面是一个示例代码: ```php function findHashTables($arr) { foreach ($arr as $key => $value) { if (is_array($value)) { echo "哈希表:$key<br>"; foreach ($value as $k => $v) { echo "键:$k => 值:$v<br>"; } echo "<br>"; } } } findHashTables($GLOBALS); ``` 在这个示例代码中,我们定义了一个名为findHashTables的函数,它接受一个数组作为参数。我们将$GLOBAL数组传递给这个函数,以查找所有的哈希表。 函数内部首先使用foreach循环遍历$GLOBAL数组,判断每个元素是否为数组。如果是数组,就打印出该数组的键和值。通过调用这个函数,我们可以找到当前脚本中的所有哈希表。 需要注意的是,这个方只能查找当前脚本中的哈希表,如果要查找其他作用域中的哈希表,可以采用类似的方,传递相应的数组参数即可。 ### 回答3: 在PHP中,你可以使用`get_defined_vars()`函数来查找所有的哈希表哈希表是一种关联数组,也称为字典或映射。在PHP中,哈希表是使用关联数组实现的。 `get_defined_vars()`函数返回一个包含所有已定义变量的数组。它会返回一个包含多个元素的数组,每个元素对应一个已定义的变量,并存储了变量的名称和值。 要查找所有的哈希表,你可以通过遍历`get_defined_vars()`返回的数组,并判断每个变量的类型是否为数组。如果是数组,则可以确定它是一个哈希表。 下面是一个示例代码,展示如何使用`get_defined_vars()`函数查找所有的哈希表: ```php $hashTables = array(); // 用于存储所有哈希表的数组 // 遍历所有已定义的变量 foreach (get_defined_vars() as $var) { // 判断变量是否为数组类型 if (is_array($var)) { // 将数组(哈希表)添加到结果数组中 $hashTables[] = $var; } } // 打印所有哈希表 foreach ($hashTables as $hashTable) { print_r($hashTable); } ``` 以上代码将打印出所有的哈希表。注意,这里只是对PHP中已定义的哈希表进行查找,未定义的哈希表不会被包含在结果中。 总结来说,通过使用`get_defined_vars()`函数和判断变量类型是否为数组,你可以很容易地查找所有的哈希表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值