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 多维数组排序(usort,uasort)
Jun 30 PHP
php tp验证表单与自动填充函数代码
Feb 22 PHP
新浪SAE云平台下使用codeigniter的数据库配置
Jun 12 PHP
ThinkPHP模板中判断volist循环的最后一条记录的验证方法
Jul 01 PHP
PHP面向对象程序设计之类常量用法实例
Aug 20 PHP
Destoon实现多表查询示例
Aug 21 PHP
php支持中文字符串分割的函数
May 28 PHP
PHP 读取文本文件内容并分页显示
Jan 02 PHP
Zend Framework教程之Zend_Controller_Plugin插件用法详解
Mar 07 PHP
php+mysql实现简单登录注册修改密码网页
Nov 30 PHP
可兼容php5与php7的cURL文件上传功能实例分析
May 11 PHP
Laravel项目中timeAgo字段语言转换的改善方法示例
Sep 16 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之require/include顺序 推荐
2011/01/02 PHP
PHP数据类型之布尔型的介绍
2013/04/28 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
CSS常用网站布局实例
2008/04/03 Javascript
JavaScript 异步调用框架 (Part 6 - 实例 &amp; 模式)
2009/08/04 Javascript
extjs 的权限问题 要求控制的对象是 菜单,按钮,URL
2010/03/09 Javascript
JS+CSS设置img在DIV中只显示Img垂直居中的部分
2013/10/24 Javascript
jquery跟js初始化加载的多种方法及区别介绍
2014/04/02 Javascript
微信小程序 用户数据解密详细介绍
2017/01/09 Javascript
jquery实现全选、全不选以及单选功能
2017/03/23 jQuery
BootStrap TreeView使用实例详解
2017/11/01 Javascript
layui实现动态和静态分页
2018/04/28 Javascript
微信小程序日期选择器实例代码
2018/07/18 Javascript
ng-repeat指令在迭代对象时的去重方法
2018/10/02 Javascript
nodejs require js文件入口,在package.json中指定默认入口main方法
2018/10/10 NodeJs
微信小程序实现原生步骤条
2019/07/25 Javascript
浅谈JS中几种轻松处理'this'指向方式
2019/09/16 Javascript
微信小程序实现点赞业务
2021/02/10 Javascript
[25:59]Newbee vs TNC 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
Python实现曲线点抽稀算法的示例
2017/10/12 Python
python random从集合中随机选择元素的方法
2019/01/23 Python
Python基础之文件读取的讲解
2019/02/16 Python
详解Django 时间与时区设置问题
2019/07/23 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
python实现按首字母分类查找功能
2019/10/31 Python
wxpython布局的实现方法
2019/11/01 Python
python 写一个水果忍者游戏
2021/01/13 Python
CSS3 RGBA色彩模式使用实例讲解
2016/04/26 HTML / CSS
苏格兰在线威士忌商店:The Whisky Barrel
2019/05/07 全球购物
施华洛世奇新加坡官网:SWAROVSKI新加坡
2020/10/06 全球购物
周年庆典答谢词
2015/01/20 职场文书
《坐井观天》教学反思
2016/02/18 职场文书
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android
js不常见操作运算符总结
2021/11/20 Javascript
MySQL 分区表中分区键为什么必须是主键的一部分
2022/03/17 MySQL