HashTree(哈希树) ——和trie类似,只是将字符换成了质数,sphinx用到了???

简介:

摘自:http://blog.csdn.net/yang_yulei/article/details/46337405

哈希树的理论基础

质数分辨定理
简单地说就是:n个不同的质数可以“分辨”的连续整数的个数和他们的乘积相等。“分辨”就是指这些连续的整数不可能有完全相同的余数序列。
(这个定理的证明详见:http://wenku.baidu.com/view/16b2c7abd1f34693daef3e58.html

例如:
从2起的连续质数,连续10个质数就可以分辨大约M(10) =2*3*5*7*11*13*17*19*23*29= 6464693230 个数,已经超过计算机中常用整数(32bit)的表达范围。连续100个质数就可以分辨大约M(100) = 4.711930 乘以10的219次方。
而按照目前的CPU水平,100次取余的整数除法操作几乎不算什么难事。在实际应用中,整体的操作速度往往取决于节点将关键字装载内存的次数和时间。一般 来说,装载的时间是由关键字的大小和硬件来决定的;在相同类型关键字和相同硬件条件下,实际的整体操作时间就主要取决于装载的次数。他们之间是一个成正比 的关系。

 

插入

我们选择质数分辨算法来建立一棵哈希树。
选择从2开始的连续质数来建立一个十层的哈希树。第一层结点为根结点,根结点下有2个结点;第二层的每个结点下有3个结点;依此类推,即每层结点的子节点数目为连续的质数。到第十层,每个结点下有29个结点。
同一结点中的子结点,从左到右代表不同的余数结果。
例如:第二层结点下有三个子节点。那么从左到右分别代表:除3余0,除3余1,除3余2.
对质数进行取余操作得到的余数决定了处理的路径。

结点结构:结点的关键字(在整个树中是唯一的),结点的数据对象,结点是否被占据的标志位(标志位为真时,关键字才被认为是有效的),和结点的子结点数组。
哈希树的节点结构

[cpp]  view plain  copy
  1. struct Node  
  2. {  
  3.     keyType      key ;  
  4.     ValueType    value ;  
  5.     bool         occupied ;    //用occupied来表示节点是否被占据。如果节点的关键字(key)有效,那么occupied应该设置位true,否则设置为false。  
  6.     struct Node* subNodes[1] ; //我们用subNodes[i]来表示节点的第i个子节点的地址。(此技术在跳跃表中有介绍,可翻看前面博客)  
  7. } ;  

(如果在建立当初就建立所有的节点,那么所消耗的计算时间和磁盘空间是巨大的。在实际使用当中,只需要初始化根节点就可以开始工作。子节点的建立是在有更多的数据进入到哈希树中的时候建立的。因此可以说哈希树和其他树一样是一个动态结构。)

 

下面我们以随机的10个数的插入为例,来图解HashTree的插入过程,这个史上最清晰的图解,你一定能看的明白^_^

有读者可能有疑问,如果一直冲突下去怎么办?首先,若关键字是整型,我们的10层哈希树完全可以分辨出来它们,这是质数分辨算法决定的。

(我们其实也可以把所有的键-值节点放在哈希树的第10层叶节点处,这第10层的满节点数就包含了所有的整数个数,但是如果这样处理的话,所有的非叶子节点作为键-值节点的索引,这样使树结构庞大,浪费空间)

【这里没有说的太清楚,此图是以2开始的连续质数创建的,即:从上到下的层级中的每个节点中的子树个数为2、3、5、7、11、13、17、19、23、29。第一层中的每个节点的子树个数为2,第二层中的每个节点子树个数为5.。。。。

上图中的子树上的数字,是其父节点的子树指针数组的索引值】


查找 

哈希树的节点查找过程和节点插入过程类似,就是对关键字用质数序列取余,根据余数确定下一节点的分叉路径,直到找到目标节点。
如上图,最小”哈希树(HashTree)在从4G个对象中找出所匹配的对象,比较次数不超过10次。也就是说:最多属于O(10)。在实际应用中,调整 了质数的范围,使得比较次数一般不超过5次。也就是说:最多属于O(5)。因此可以根据自身需要在时间和空间上寻求一个平衡点。

 

删除 

哈希树的节点删除过程也很简单,哈希树在删除的时候,并不做任何结构调整。
只是先查到到要删除的节点,然后把此节点的“占位标记”置为false即可(即表示此节点为空节点,但并不进行物理删除)。

 

优点

1、结构简单

2、查找迅速

3、结构不变

从删除算法中可以看出,哈希树在删除的时候,并不做任何结构调整。 

缺点

非排序性














本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6249605.html,如需转载请自行联系原作者


相关文章
|
2月前
|
网络协议 应用服务中间件 网络安全
2026阿里云免费SSL证书申请流程|零基础一步到位,超简单
2026年阿里云免费SSL证书(Digicert品牌)申请指南:零基础一步到位!单账号每年可领20张,有效期3个月(非1年)。全程免费,在数字证书管理服务控制台操作——选“个人测试证书”→提交申请→DNS验证(TXT记录)→审核通过后下载PEM/PFX等多格式证书。到期不续费,重新申请即可。
368 6
|
7月前
|
自然语言处理 前端开发 安全
别人还在摸索,你用这篇Hoobuy淘宝代购集运系统搭建攻略开拓欧美反向海淘市场!
淘宝代购集运系统为海外用户提供一站式中国电商购物解决方案,集成商品抓取、多语言展示、本地支付、国际物流与订单追踪功能,支持多平台数据同步与合规运营,通过技术整合破解语言、支付、物流难题,助力逆向海淘高效便捷。
|
3月前
|
人工智能 架构师 Java
大模型企业级 LLM API架构演进:重构 Java/Python 的 RAG 与 Agent 系统的六种核心策略
在 AI 全面落地的 2026 年,企业架构师的核心命题已从“如何调用”转向“如何治理”。本文结合最新的 大模型(LLM)技术趋势,深入剖析 RAG、Agent 与微调等六大 AI 定制策略。我们将探讨如何利用标准化的 LLM API 聚合层,构建高可用、低成本的企业级 AI 基础设施,助力 AI 大模型在业务中的深度应用。
402 0
|
人工智能 Kubernetes Cloud Native
跨越鸿沟:PAI-DSW 支持动态数据挂载新体验
本文讲述了如何在 PAI-DSW 中集成和利用 Fluid 框架,以及通过动态挂载技术实现 OSS 等存储介质上数据集的快速接入和管理。通过案例演示,进一步展示了动态挂载功能的实际应用效果和优势。
阿里云服务器购买后,怎么申请开具发票?
阿里云用户可在用户中心的发票管理页面开具电子或纸质发票。首次开票需设置发票抬头,支持个人或企业,可选增值税普通或专用发票。个人账号无法直接开企业发票,需变更实名认证。发票税率因产品而异,通常为6%或13%。发票抬头可修改,纸质发票邮寄费用由阿里云承担(特殊情况除外)。电子发票同样可报销。更多详情见阿里云帮助中心。
1135 106
|
网络性能优化 数据安全/隐私保护
什么是国际专线网络?国际专线网络的特点
国际专线网络是连接不同国家和地区的专用通信线路,提供高速、可靠的数据传输服务。它具备高带宽、专用通道、高安全性、广泛覆盖和服务质量保障等优点,适用于跨国企业和组织的高效通信需求。然而,其建设和维护成本较高,需综合考虑。
1250 3
|
人工智能 自然语言处理 数据库
从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享
【9月更文挑战第3天】从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享
|
机器学习/深度学习 人工智能 安全
【Python专栏】Python的历史及背景介绍
【Python专栏】Python的历史及背景介绍
2024 6
|
Go 开发者
什么是 Golang 包?详解 Go 语言的包系统
【8月更文挑战第31天】
421 0
|
C++ Python
几行python代码搞定农历转阳历,阳历转农历的问题
关于这个问题,网上大部分的实现都是基于查表实现。所以查询范围非常有限。如果处理古人的生辰的信息(比如祖谱信息等)就变得非常棘手。本文介绍如何最精简的代码优雅的处理此类信息
7976 0