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模板,主要想体现一下思路
Dec 25 PHP
PHP中文汉字验证码
Apr 08 PHP
Discuz! Passport 通行证整合
Mar 27 PHP
PHP及Zend Engine的线程安全模型分析
Nov 10 PHP
解析wamp5下虚拟机配置文档
Jun 27 PHP
php+ajax 实现输入读取数据库显示匹配信息
Oct 08 PHP
PHP对象相关知识总结
Apr 09 PHP
Yii2使用表单上传文件的实例代码
Aug 03 PHP
原生php实现excel文件读写的方法分析
Apr 25 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
May 08 PHP
TP3.2框架分页相关实现方法分析
Jun 03 PHP
PHP中的输出echo、print、printf、sprintf、print_r和var_dump的示例代码
Dec 01 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
深入理解PHP类的自动载入机制
2016/09/16 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
PHP设计模式之原型设计模式原理与用法分析
2018/04/25 PHP
又一个小巧的图片预加载类
2007/05/05 Javascript
JavaScript CSS修改学习第六章 拖拽
2010/02/19 Javascript
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
JavaScript中圆括号()和方括号[]的特殊用法疑问解答
2013/08/06 Javascript
中止javascript执行的方法
2014/02/14 Javascript
一个不错的js html页面倒计时可精确到秒
2014/10/22 Javascript
在JavaScript中正确引用bind方法的应用
2015/05/11 Javascript
快速学习JavaScript的6个思维技巧
2015/10/13 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
用 js 的 selection range 操作选择区域内容和图片
2017/04/18 Javascript
微信小程序实现表单校验功能
2020/03/30 Javascript
详解vue-cli项目中的proxyTable跨域问题小结
2018/02/09 Javascript
详解webpack-dev-server 设置反向代理解决跨域问题
2018/04/18 Javascript
vue实现分页加载效果
2019/12/24 Javascript
深入理解Antd-Select组件的用法
2020/02/25 Javascript
基于ajax实现上传图片代码示例解析
2020/12/03 Javascript
使用wxpython实现的一个简单图片浏览器实例
2014/07/10 Python
对Tensorflow中权值和feature map的可视化详解
2018/06/14 Python
Python socket处理client连接过程解析
2020/03/18 Python
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
Toppik顶丰增发纤维官网:解决头发稀疏
2017/12/30 全球购物
什么造成了Java里面的异常
2016/04/24 面试题
简单的JAVA编程面试题
2013/03/19 面试题
趣味运动会活动方案
2014/02/12 职场文书
人资专员岗位职责
2014/04/04 职场文书
中秋节国旗下演讲稿
2014/09/05 职场文书
小学语文复习计划
2015/01/19 职场文书
邀请函怎么写
2015/01/30 职场文书
公司借条范本
2015/05/25 职场文书
小学体育组工作总结
2015/08/13 职场文书
小学数学继续教育研修日志
2015/11/13 职场文书
2016年保险公众宣传日活动总结
2016/04/05 职场文书
Python 第三方库 openpyxl 的安装过程
2022/12/24 Python