拉链法解决Hash节点冲突问题

<?php
/*
 * hash::拉链法解决hash节点存储冲突问题
 * ::2014-07-02
 * ::Small_Kind
 */
class small_hash {

  private $size = 20;//hash节点大小
  private $zone = null;//hash空间

  //实例化函数,并设置一个初始hash节点大小,如果节点大小为null,则为默认节点大小
  final public function __construct($size = null){
    if(!is_null($size))$this->size = $size;//
    $this->zone = new SplFixedArray($this->size);//
  }

  //times33::计算key的hash值,并进行节点大小的取模工作
  //::实现流程1、计算key长度2、循环长度,并将每个字符转换成asicc码后*33
  final private function hash_times33($key){
      if(empty($key))return false;//key==>empty
      $strlen = strlen($key);
      $hash_val = 0;
      for($i=0;$i<$strlen;$i++){
          $hash_val += ($hash_val * 33) + ord($key{$i});
      }
      return ($hash_val & 0x7FFFFFFF) % $this->size;
  }

  //set::通过拉链法进行key->value对应的值设置
  final public function set($key,$value){
      if(empty($key) || empty($value))return false;//empty
      $index = $this->hash_times33($key);
      //如果不存在此节点的数据,则向该节点添加第一组数据
      if(isset($this->zone[$index])){
          //key、value、拉链对象[当该节点已存在1个或多组数据的时候,将之前的数据赋值给最新的一组data]
          //也就是说在查询时候相当于一种后进先出的原则,不断将最新的数据放在最前面,以此形成一种阶梯形式
          $data = array($key,serialize($value),$this->zone[$index]);
      }else{
          $data = array($key,serialize($value),null);//key、value、拉链对象[当该节点是第一次有值的时候,拉链对象为null]
      }
      return $this->zone[$index] = $data;//最后将完整的data赋值给该节点
  }

  //get::通过key获取对应hash后对应的的节点,循环该对象节点,然后通过key值匹配节点中的key,并将值进行返回
  final public function get($key){
      $index  = $this->hash_times33($key);
      $handle = new stdClass();//初始化一个对象
      $handle = (array)$this->zone[$index];//查询该key对应的节点
      return $this->for_match($key,$handle);//将对象数组送入匹配函数进行迭代查询
  }

  //for_match::通过key对handle进行迭代查询,查询到了即返回,没有查询到则返回一个false
  final public function for_match($key,$handle){
      if(is_array($handle)){
          if($handle[0] == $key){
              return unserialize($handle[1]);//如果找到值了,则对值进行返回
          }else{
              return $this->for_match($key,$handle[2]);//否则继续迭代该方法
          }
      }
  }
}

$hand = new small_hash();
$hand->set(‘Libin‘,‘WWW.BAIDU.COM‘);
$hand->set(‘d24150ddd‘,‘WWW.PHP.COM‘);
var_dump($hand->get(‘Libin‘));
var_dump($hand->get(‘d24150ddd‘));
?>

拉链法解决Hash节点冲突问题,布布扣,bubuko.com

时间: 2024-10-26 16:55:32

拉链法解决Hash节点冲突问题的相关文章

算法学习 - Hash Table操作,分离链接法解决哈希冲突

分离链接法 hash table是映射机制的,最大的优点就是它的操作是O(1)级别的.但是会出现哈希冲突,这就需要几种办法来解决.这里先说一种:分离链接法. 就是当插入的位置已经存在一个值之后,那么在这个值之后插入,就可以了,也叫拉链法.(但是其实会降低查找速度,变成O(n)级别) 下面是代码: // // main.cpp // HashTable_SeparateChaining // // Created by Alps on 14-8-5. // Copyright (c) 2014年

拉链法解决hashtable冲突问题

拉链法解决冲突.拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表.如果不能理解我的文字,请看下面的示例,看一下打印信息就明白了.拉链法是什么,就是链表. class HashNode{ public $key; public $value; public $nextNode; public function __construct($key, $value, $nextNode=Nu

算法学习 - HashTable开放地址法解决哈希冲突

开放地址法解决哈希冲突 线性开放地址法 线性开放地址法就是在hash之后,当发现在位置上已经存在了一个变量之后,放到它下一个位置,假如下一个位置也冲突,则继续向下,依次类推,直到找到没有变量的位置,放进去. 平方开放地址法 平方地址法就是在hash之后,当正确位置上存在冲突,不放到挨着的下一个位置,而是放到第2^0位置,假如继续冲突放到2^1的位置,依次2^3... 直到遇到不冲突的位置放进去. 双散列开放地址法 双散列同上,不过不是放到2^的位置,而是放到key - hash(key, tab

数据结构--开放定址法解决散列冲突时几种探测法的比较

开放定址法解决散列冲突时主要有线性探测法,平方探测法和双散列法,以下代码通过插入大量随机数,来统计几种探测法产生冲突的次数. #include<iostream> using namespace std; #define MinTablesize 10 #define Num 3000 typedef unsigned int Index; typedef Index Position; struct Hashtal; typedef struct Hashtal *Hashtable; in

【干货】C++哈希桶(开链法解决哈希冲突)类的实现

开链法(哈希桶)是解决哈希冲突的常用手法,结构如下: 数据结构的设计思路是这样的,定义一个K-V的链式节点(Node),以数组方式存储节点指针 实现代码如下: #include<vector> #include"HashTable.h" size_t GetSize() { static size_t index = 0; const int _PrimeSize = 28; static const unsigned long _PrimeList[_PrimeSize]

解决Hash碰撞冲突方法总结

我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突.如下将介绍如何处理冲突,当然其前提是一致性hash. 1.开放地址法 开放地执法有一个公式:Hi=(H(key)+di) MOD m i=1,2,-,k(k<=m-1)其中,m为哈希表的表长.di 是产生冲突的时候的增量序列.如果di值可能为1,2,3,-m-1,称线性探测再散列.如果di取1,则每次冲突之后

poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)

Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30529   Accepted: 8033 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Y

PHP核心技术与最佳实践之Hash表冲突

PHP核心技术与最佳实践之Hash表冲突 接着上一篇文章,测试后输出value1value2.当 $ht->insert('key12','value12'); Echo $ht ->find('key12');时, 发现输出value12value12.这是什么原因呢? 这个问题称为Hash表的冲突.由于insert的是字符串,采用的算法是将字符串的ASIIC码相加,按照此方法,冲突产生了.通过打印key12和key1的Hash值,发现他们都为8,也就说,value1和value12同时被存

解决hash冲突之分离链接法

解决hash冲突之分离链接法 分离链接法:其做法就是将散列到同一个值的所有元素保存到一个表中. 这样讲可能比较抽象,下面看一个图就会很清楚,图如下 相应的实现可以用分离链接散列表来实现(其实就是一个linkedList数组) 至于基本的增加.删除和查询的思路都是先根据散列函数来确定遍历哪个链表.然后再到被确定的链表中执行一次查找,然后再进行相应的操作. 接下来就讲几个注意点吧 (一)什么时候需要rehash来扩大散列表的大小 讲这个的时候,先介绍一下什么是装填因子. 装填因子 = 关键字个数 /