数据结构-PHP 哈希表(Hash Table)的实现

数据结构-PHP 哈希表(Hash Table)的实现

这篇文章主要介绍一下哈希表(Hash Table)的实现原理,哈希表(Hash Table) 也叫散列表,它通过把关键码值(key-value)映射到表中一个位置来访问,以加快其查找的速度。这个映射函数叫做哈希函数,存放记录的数组叫哈希表(Hash Table)

1.哈希表(Hash Table)的特点

  • 访问速度很快,将指定的 Key 都映射到一个地址上,在访问时,可以直接跳到那个地址。
  • 空间换时间,哈希表充分体现了空间换时间的思想。
  • 无序,哈希表是无序的。它为了能快速访问元素,值是根据哈希函数直接找到存储地址的。
  • 可能会产生哈希冲突,不同的值通过哈希函数可能存在相同值的情况,这时就需要采用冲突解决方案。

2.哈希函数的原理

下面举几个简单的 哈希函数 实现原理,主要说明如何将不同类型的值转化为一个小整数(小整数可以在数组中表示索引,即表示地址):

2.1 大整数转化为小整数(数组索引)

一个最简单的办法是 模(mod) 一个 素数
在这里插入图片描述

Tips:从图中可以看出,不同的数对一个 素数 模值区分度比较高,分布更加均匀。

下面是有人研究好的一个列表,其中 lwr 表示你取值范围的下界,upr 表示你取值范围的上界,prime 表示该范围的值对该值求区分度最好:
在这里插入图片描述

2.2 浮点型转化为小整数(数组索引)

可以先将浮点型扩大倍数转化为整型,然后按照大整数的方式处理即可。

2.3 字符串
十进制表示数字: 166 = 1 * 10^2 + 6 * 10^1 + 6 * 10^0
二十六进制表示字母: code = c * 26^3 + o * 26^2 + d * 26^1 + e * 26^0
hash(code) = (c * B^3 + o * B^2 + d * B^1 + e * B^0) % M
hash(code) = ((((c * B) + o) * B + d) * B + e) % M

Tips:其中 B 表示进制,M 表示一个合适的 素数

2.4 用 PHP 代码实现的 HashCode 类

下面这个类可以实现输入一个字符串,然后返回一个正整数的哈希值:

<?php

trait HashCode
{
    function hashCode64($str) {
        $str = (string)$str;
        $hash = 0;
        $len = strlen($str);
        if ($len == 0 )
            return $hash;

        for ($i = 0; $i < $len; $i++) {
            $h = $hash << 5;
            $h -= $hash;
            $h += ord($str[$i]);
            $hash = $h;
            $hash &= 0x7FFFFFFF;
        }
        return $hash;
    }
}

Tips:这里简单封装成 trait HashCode 方便其他类调用,其中 $hash &= 0x7FFFFFFF 的意思是将输出值最高位符号位保证为0,表示正数输出。

3. 定义一个带有哈希函数的 Student 类

为了方便对哈希值的理解,下面定义一个学生类(Student),该类中包含 年级(grade)班级(class)姓氏(firstName)名字(lastName)

<?php


class Student
{
    use HashCode;

    //学生年级
    public $grade = null;
    //班级
    public $class = null;
    //姓氏
    public $firstName = null;
    //名字
    public $lastName = null;

    public function __construct($grade, $class, $firstName, $lastName)
    {
        $this->g
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值