php 实现Hash表功能实例详解


Posted in PHP onNovember 29, 2016

php 实现Hash表功能

Hash表作为最重要的数据结构之一,也叫做散列表。使用PHP实现Hash表的功能。PHP可以模拟实现Hash表的增删改查。通过对key的映射到数组中的一个位置来访问。映射函数叫做Hash函数,存放记录的数组称为Hash表。

Hash函数把任意长度的和类型的key转换成固定长度输出。不同的key可能拥有相同的hash。
Hash表的时间复杂度为O(1)

<?php
class HashTable{
  private $arr = array();
  private $size = 10;
  public function __construct(){
    //SplFixedArray创建的数组比一般的Array()效率更高,因为更接近C的数组。创建时需要指定尺寸
    $this->arr = new SplFixedArray($this->size);
  }
  /**
   * Description: 简单hash算法。输入key,输出hash后的整数
   * @param $key
   * @return int
   */
  private function simpleHash($key){
    $len = strlen($key);
    //key中每个字符所对应的ASCII的值
    $asciiTotal = 0;
    for($i=0; $i<$len; $i++){
      $asciiTotal += ord($key[$i]);
    }
    return $asciiTotal % $this->size;
  }
  /**
   * Description: 赋值
   * @param $key
   * @param $value
   * @return bool
   */
  public function set($key, $value){
    $hash = $this->simpleHash($key);
    $this->arr[$hash] = $value;
    return true;
  }
  /**
   * Description: 取值
   * @param $key
   * @return mixed
   */
  public function get($key){
    $hash = $this->simpleHash($key);
    return $this->arr[$hash];
  }
  public function getList(){
    return $this->arr;
  }
  public function editSize($size){
    $this->size = $size;
    $this->arr->setSize($size);
  }
}
?>

 下面对我们的HashTable进行测试。

<?php
//测试1
$arr = new HashTable();
for($i=0; $i<15; $i++){
  $arr->set('key'.$i, 'value'.$i);
}
print_r($arr->getList());

//测试2
$arr->editSize(15);
for($i=0; $i<15; $i++){
  $arr->set('key'.$i, 'value'.$i);
}
print_r($arr->getList());
?>

 改变了值之后可以存放更多的元素。但是仍然存在不同的key可能产生相同的hash值,那么赋值的时候后操作会覆盖前操作的问题。这种冲突的问题我们来用拉链法解决。

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

创建一个HashNode类,用来存储key和value的值,并且存储相同hash的另一个元素。在同一条链上,查找越后的元素越费时。时间复杂度为O(n).

<?php
class HashNode{
  public $key;
  public $value;
  public $nextNode;
  public function __construct($key, $value, $nextNode=Null){
    $this->key = $key;
    $this->value = $value;
    $this->nextNode = $nextNode;
  }
}
class NewHashTable{
  private $arr;
  private $size = 10;
  public function __construct(){
    $this->arr = new SplFixedArray($this->size);
  }
  private function simpleHash($key){
    $asciiTotal = 0;
    $len = strlen($key);
    for($i=0; $i<$len; $i++){
      $asciiTotal += ord($key[$i]);
    }
    return $asciiTotal % $this->size;
  }
  public function set($key, $value){
    $hash = $this->simpleHash($key);
    if(isset($this->arr[$hash])){
      $newNode = new HashNode($key, $value, $this->arr[$hash]);
    }else{
      $newNode = new HashNode($key, $value, null);
    }
    $this->arr[$hash] = $newNode;
    return true;
  }
  public function get($key){
    $hash = $this->simpleHash($key);
    $current = $this->arr[$hash];
    while(!empty($current)){
      if($current->key == $key){
        return $current->value;
      }
      $current = $current->nextNode;
    }
    return NULL;
  }
  public function getList(){
    return $this->arr;
  }
}
?>

对我们新的HashTable进行测试

<?php
//测试1
$newArr = new NewHashTable();
for($i=0; $i<30; $i++){
  $newArr->set('key'.$i, 'value'.$i);
}
print_r($newArr->getList());
var_dump($newArr->get('key3'));
?>

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
初级的用php写的采集程序
Mar 16 PHP
PHP隐形一句话后门,和ThinkPHP框架加密码程序(base64_decode)
Nov 02 PHP
php echo, print, print_r, sprintf, var_dump, var_expor的使用区别
Jun 20 PHP
php求两个目录的相对路径示例(php获取相对路径)
Mar 27 PHP
PHP return语句另类用法不止是在函数中
Sep 17 PHP
一个PHP实现的轻量级简单爬虫
Jul 08 PHP
浅谈php错误提示及查错方法
Jul 14 PHP
又十个超级有用的PHP代码片段
Sep 24 PHP
PHP入门教程之PHP操作MySQL的方法分析
Sep 11 PHP
[原创]php实现 data url的图片生成与保存
Dec 04 PHP
php实现评论回复删除功能
May 23 PHP
解决php写入数据库乱码的问题
Sep 17 PHP
php文件上传 你真的掌握了吗
Nov 28 #PHP
php微信公众号js-sdk开发应用
Nov 28 #PHP
php微信高级接口调用方法(自定义菜单接口、客服接口、二维码)
Nov 28 #PHP
php微信公众平台交互与接口详解
Nov 28 #PHP
php微信公众号开发模式详解
Nov 28 #PHP
jQuery+php简单实现全选删除的方法
Nov 28 #PHP
PHP中的use关键字及文件的加载详解
Nov 28 #PHP
You might like
深入了解php4(2)--重访过去
2006/10/09 PHP
php图片验证码代码
2008/03/27 PHP
php简单对象与数组的转换函数代码(php多层数组和对象的转换)
2011/05/18 PHP
php实现根据词频生成tag云的方法
2015/04/17 PHP
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
2013/01/27 Javascript
原生js实现改变随意改变div属性style的名称和值的结果
2013/09/26 Javascript
通过javascript把图片转化为字符画
2013/10/24 Javascript
js浏览器本地存储store.js介绍及应用
2014/05/13 Javascript
JavaScript中使用arguments获得函数传参个数实例
2014/08/27 Javascript
javascript中innerText和innerHTML属性用法实例分析
2015/05/13 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
jQuery实现鼠标双击Table单元格变成文本框及输入内容后更新到数据库的方法
2015/11/25 Javascript
JS提交form表单实例分析
2015/12/10 Javascript
ES6中字符串string常用的新增方法小结
2017/11/07 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
2018/10/09 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
2018/12/06 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
2020/11/24 Javascript
vue从后台渲染文章列表以及根据id跳转文章详情详解
2020/12/14 Vue.js
Python中使用PyHook监听鼠标和键盘事件实例
2014/07/18 Python
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
Python多线程和队列操作实例
2015/06/21 Python
Python Queue模块详细介绍及实例
2016/12/27 Python
tensorflow dataset.shuffle、dataset.batch、dataset.repeat顺序区别详解
2020/06/03 Python
HTML5 form标签之解放表单验证、增加文件上传、集成拖放的使用方法
2013/04/24 HTML / CSS
机械绘图员岗位职责
2013/11/19 职场文书
博士导师推荐信
2015/03/25 职场文书
个人廉政承诺书
2015/04/28 职场文书
法定授权委托证明书
2015/06/18 职场文书
有关浪费资源的建议书
2015/09/14 职场文书
公司岗位说明书
2015/10/08 职场文书
2016年“世界环境日”校园广播稿
2015/12/18 职场文书
2016党校学习心得体会范文
2016/01/07 职场文书
党员反邪教心得体会
2016/01/15 职场文书
了解Kubernetes中的Service和Endpoint
2022/04/01 Servers