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 什么是PEAR?(第二篇)
Mar 19 PHP
php set_magic_quotes_runtime() 函数过时解决方法
Jul 08 PHP
PHP递归返回值时出现的问题解决办法
Feb 19 PHP
解析用PHP实现var_export的详细介绍
Jun 20 PHP
php使用curl出现Expect:100-continue解决方法
Mar 03 PHP
php判断表是否存在的方法
Jun 18 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
Sep 29 PHP
深入理解PHP JSON数组与对象
Jul 19 PHP
PHP中用mysqli面向对象打开连接关闭mysql数据库的方法
Nov 05 PHP
PHP环形链表实现方法示例
Sep 15 PHP
PHP bin2hex()函数基础实例讲解
Feb 11 PHP
php获取是星期几的的一些常用姿势
Dec 15 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生成文件
2007/01/15 PHP
php 更新数据库中断的解决方法
2009/06/05 PHP
PHP缓存技术的多种方法小结
2012/08/14 PHP
ajax php传递和接收变量实现思路及代码
2012/12/19 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
php简单构造json多维数组的方法示例
2017/06/08 PHP
PHP实现生成数据字典功能示例
2018/05/24 PHP
laravel 中某一字段自增、自减的例子
2019/10/11 PHP
javascript document.execCommand() 常用解析
2009/12/14 Javascript
jquery下实现overlay遮罩层代码
2010/08/25 Javascript
jQuery-serialize()输出序列化form表单值的方法
2012/12/26 Javascript
jquery使用$(element).is()来判断获取的tagName
2014/08/24 Javascript
js带缩略图的图片轮播效果代码分享
2015/09/14 Javascript
js实现点击按钮弹出上传文件的窗口
2016/12/23 Javascript
详解如何在angular2中获取节点
2017/11/23 Javascript
Angular2实现组件交互的方法分析
2017/12/19 Javascript
web前端vue之CSS过渡效果示例
2018/01/10 Javascript
JS原型和原型链原理与用法实例详解
2020/02/05 Javascript
[01:16:13]DOTA2-DPC中国联赛 正赛 SAG vs Dragon BO3 第一场 2月22日
2021/03/11 DOTA
Python实现选择排序
2017/06/04 Python
Python利用pandas计算多个CSV文件数据值的实例
2018/04/19 Python
Python函数返回不定数量的值方法
2019/01/22 Python
Django实现whoosh搜索引擎使用jieba分词
2020/04/08 Python
python3环境搭建过程(利用Anaconda+pycharm)完整版
2020/08/19 Python
浅析Python 中的 WSGI 接口和 WSGI 服务的运行
2020/12/09 Python
在vscode中启动conda虚拟环境的思路详解
2020/12/25 Python
CSS3 @font-face属性使用指南
2014/12/12 HTML / CSS
HTML5实现直播间评论滚动效果的代码
2020/05/27 HTML / CSS
美国高档百货Nordstrom的折扣店:Nordstrom Rack
2017/11/13 全球购物
德国最大的网上足球商店:11teamsports
2019/09/11 全球购物
写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数
2016/04/13 面试题
毕业生教师求职信
2013/10/20 职场文书
工程业务员工作职责
2013/12/07 职场文书
2014年班组长工作总结
2014/11/20 职场文书
对Golang中的FORM相关字段理解
2021/05/02 Golang
Python爬虫基础之初次使用scrapy爬虫实例
2021/06/26 Python