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中$_SERVER的详细参数与说明
Jul 29 PHP
php 注释规范
Mar 29 PHP
关于file_get_contents返回为空或函数不可用的解决方案
Jun 24 PHP
php curl post 时出现的问题解决
Jan 30 PHP
PHP5.3安装Zend Guard Loader图文教程
Sep 29 PHP
php数字每三位加逗号的功能函数
Oct 22 PHP
header与缓冲区之间的深层次分析
Jul 30 PHP
详解PHP中websocket的使用方法
Sep 15 PHP
PHP实现的Redis多库选择功能单例类
Jul 27 PHP
Laravel关系模型指定条件查询方法
Oct 10 PHP
在 PHP 和 Laravel 中使用 Traits的方法
Nov 13 PHP
php将xml转化对象的实例详解
Nov 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
Extended CHM PHP 语法手册之 DIY
2006/10/09 PHP
PHP中MVC模式的模板引擎开发经验分享
2011/03/23 PHP
PHP获取youku视频真实flv文件地址的方法
2014/12/23 PHP
如何实现php图片等比例缩放
2015/07/28 PHP
PHP简单实现二维数组的矩阵转置操作示例
2017/11/24 PHP
一个分享按钮的插件使用介绍(可扩展,内附开发制作流程)
2011/09/19 Javascript
深入理解JavaScript系列(47):对象创建模式(上篇)
2015/03/04 Javascript
JavaScript中扩展Array contains方法实例
2020/08/23 Javascript
浅析JavaScript作用域链、执行上下文与闭包
2016/02/01 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
2016/02/21 Javascript
Angularjs中的事件广播 —全面解析$broadcast,$emit,$on
2016/05/17 Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
2017/02/23 Javascript
ES6中数组array新增方法实例总结
2017/11/07 Javascript
微信小程序下拉框组件使用方法详解
2018/12/28 Javascript
微信小程序实现同一页面取值的方法分析
2019/04/30 Javascript
Layui 数据表格批量删除和多条件搜索的实例
2019/09/04 Javascript
使用PyInstaller将python转成可执行文件exe笔记
2018/05/26 Python
在python中获取div的文本内容并和想定结果进行对比详解
2019/01/02 Python
pygame库实现移动底座弹球小游戏
2020/04/14 Python
pyspark给dataframe增加新的一列的实现示例
2020/04/24 Python
解决python执行较大excel文件openpyxl慢问题
2020/05/15 Python
10个python爬虫入门基础代码实例 + 1个简单的python爬虫完整实例
2020/12/16 Python
css3截图_动力节点Java学院整理
2017/07/11 HTML / CSS
Lampegiganten丹麦:欧洲领先的照明网上商店
2018/04/25 全球购物
Haggar官网:美国男装品牌
2020/02/16 全球购物
Bath & Body Works阿联酋:在线购买沐浴和身体用品
2021/02/27 全球购物
非常详细的C#面试题集
2016/07/13 面试题
软件测试面试题
2014/01/05 面试题
授权委托书样本
2014/04/03 职场文书
保护环境倡议书500字
2014/05/19 职场文书
2014最新党员批评与自我批评材料
2014/09/24 职场文书
2015年教学管理工作总结
2015/05/20 职场文书
服装店员工管理制度
2015/08/07 职场文书
2015年终个人政治思想工作总结
2015/11/24 职场文书
《兰兰过桥》教学反思
2016/02/20 职场文书
Redis实现分布式锁的五种方法详解
2022/06/14 Redis