Heim > Artikel > Backend-Entwicklung > 拉链法解决Hash节点冲突相关问题_PHP教程
<?<span>php </span><span>/*</span><span> * hash::拉链法解决hash节点存储冲突问题 * ::2014-07-02 * ::Small_Kind </span><span>*/</span> <span>class</span><span> small_hash { </span><span>private</span> <span>$size</span> = 20;<span>//</span><span>hash节点大小</span> <span>private</span> <span>$zone</span> = <span>null</span>;<span>//</span><span>hash空间 //实例化函数,并设置一个初始hash节点大小,如果节点大小为null,则为默认节点大小</span> <span>final</span> <span>public</span> <span>function</span> __construct(<span>$size</span> = <span>null</span><span>){ </span><span>if</span>(!<span>is_null</span>(<span>$size</span>))<span>$this</span>->size = <span>$size</span>;<span>// </span> <span>$this</span>->zone = <span>new</span> SplFixedArray(<span>$this</span>->size);<span>// </span><span> } </span><span>//</span><span>times33::计算key的hash值,并进行节点大小的取模工作 //::实现流程1、计算key长度2、循环长度,并将每个字符转换成asicc码后*33</span> <span>final</span> <span>private</span> <span>function</span> hash_times33(<span>$key</span><span>){ </span><span>if</span>(<span>empty</span>(<span>$key</span>))<span>return</span> <span>false</span>;<span>//</span><span>key==>empty</span> <span>$strlen</span> = <span>strlen</span>(<span>$key</span><span>); </span><span>$hash_val</span> = 0<span>; </span><span>for</span>(<span>$i</span>=0;<span>$i</span><<span>$strlen</span>;<span>$i</span>++<span>){ </span><span>$hash_val</span> += (<span>$hash_val</span> * 33) + <span>ord</span>(<span>$key</span>{<span>$i</span><span>}); } </span><span>return</span> (<span>$hash_val</span> & 0x7FFFFFFF) % <span>$this</span>-><span>size; } </span><span>//</span><span>set::通过拉链法进行key->value对应的值设置</span> <span>final</span> <span>public</span> <span>function</span> set(<span>$key</span>,<span>$value</span><span>){ </span><span>if</span>(<span>empty</span>(<span>$key</span>) || <span>empty</span>(<span>$value</span>))<span>return</span> <span>false</span>;<span>//</span><span>empty</span> <span>$index</span> = <span>$this</span>->hash_times33(<span>$key</span><span>); </span><span>//</span><span>如果不存在此节点的数据,则向该节点添加第一组数据</span> <span>if</span>(<span>isset</span>(<span>$this</span>->zone[<span>$index</span><span>])){ </span><span>//</span><span>key、value、拉链对象[当该节点已存在1个或多组数据的时候,将之前的数据赋值给最新的一组data] //也就是说在查询时候相当于一种后进先出的原则,不断将最新的数据放在最前面,以此形成一种阶梯形式</span> <span>$data</span> = <span>array</span>(<span>$key</span>,<span>serialize</span>(<span>$value</span>),<span>$this</span>->zone[<span>$index</span><span>]); }</span><span>else</span><span>{ </span><span>$data</span> = <span>array</span>(<span>$key</span>,<span>serialize</span>(<span>$value</span>),<span>null</span>);<span>//</span><span>key、value、拉链对象[当该节点是第一次有值的时候,拉链对象为null]</span> <span> } </span><span>return</span> <span>$this</span>->zone[<span>$index</span>] = <span>$data</span>;<span>//</span><span>最后将完整的data赋值给该节点</span> <span> } </span><span>//</span><span>get::通过key获取对应hash后对应的的节点,循环该对象节点,然后通过key值匹配节点中的key,并将值进行返回</span> <span>final</span> <span>public</span> <span>function</span> get(<span>$key</span><span>){ </span><span>$index</span> = <span>$this</span>->hash_times33(<span>$key</span><span>); </span><span>$handle</span> = <span>new</span> stdClass();<span>//</span><span>初始化一个对象</span> <span>$handle</span> = (<span>array</span>)<span>$this</span>->zone[<span>$index</span>];<span>//</span><span>查询该key对应的节点</span> <span>return</span> <span>$this</span>->for_match(<span>$key</span>,<span>$handle</span>);<span>//</span><span>将对象数组送入匹配函数进行迭代查询</span> <span> } </span><span>//</span><span>for_match::通过key对handle进行迭代查询,查询到了即返回,没有查询到则返回一个false</span> <span>final</span> <span>public</span> <span>function</span> for_match(<span>$key</span>,<span>$handle</span><span>){ </span><span>if</span>(<span>is_array</span>(<span>$handle</span><span>)){ </span><span>if</span>(<span>$handle</span>[0] == <span>$key</span><span>){ </span><span>return</span> <span>unserialize</span>(<span>$handle</span>[1]);<span>//</span><span>如果找到值了,则对值进行返回</span> }<span>else</span><span>{ </span><span>return</span> <span>$this</span>->for_match(<span>$key</span>,<span>$handle</span>[2]);<span>//</span><span>否则继续迭代该方法</span> <span> } } } } </span><span>$hand</span> = <span>new</span><span> small_hash(); </span><span>$hand</span>->set('Libin','WWW.BAIDU.COM'<span>); </span><span>$hand</span>->set('d24150ddd','WWW.PHP.COM'<span>); </span><span>var_dump</span>(<span>$hand</span>->get('Libin'<span>)); </span><span>var_dump</span>(<span>$hand</span>->get('d24150ddd'<span>)); </span>?>