二叉树和哈希表的优缺点对比与选择

二叉树(binary tree)和哈希表(hash table)都是很基本的数据结构,但是我们要怎么从两者之间进行选择呢?他们的不同是什么?优缺点分别是什么?

回答这个问题不是一两句话可以说清楚的,原因是在不同的情况下,选择的依据肯定也不同。首先来回顾一下这两个数据结构:

哈希表使用hash function来对输入的数据分配index到哈希表对应的槽中。假设有一个哈希表的size是100,而我们输入的数据是从0~99,我们要把输入数据储存到哈希表中。理论上来说,该哈希表插入和查找操作的时间复杂度都是O(1)。

二叉树遵循右子树大于根节点,左子树小于根节点的原则进行数据的插入和保存。如果这个树的平衡的,那么,对于每个元素的插入和查找操作的时间复杂度是O(log(n)),n是树的节点个数,log(n)通常是树的深度。当然,对于不平衡的情况,那就需要更复杂的数据结构的树(红黑树等)进行处理。

上文似乎得出结论哈希表要好于二叉树,但是it is not always the case。哈希表有以下几个突出的缺点:

  1. 当更多的数插入时,哈希表冲突的可能性就更大。对于冲突,哈希表通常有两种解决方案:第一种是线性探索,相当于在冲突的槽后建立一个单链表,这种情况下,插入和查找以及删除操作消耗的时间会达到O(n),且该哈希表需要更多的空间进行储存。第二种方法是开放寻址,他不需要更多的空间,但是在最坏的情况下(例如所有输入数据都被map到了一个index上)的时间复杂度也会达到O(n)。

  2. 所以,在决定建立哈希表之前,最好可以估计输入的数据的size。否则,resize哈希表的过程将会是一个非常消耗时间的过程。例如,如果现在你的哈希表的长度是100,但是现在有第101个数要插入。这时,不仅哈希表的长度可能要扩展到150,且扩展之后所有的数都需要重新rehash。

  3. 哈希表中的元素是没有被排序的。然而,有些情况下,我们希望储存的数据是有序的。

另一方面,我们讨论二叉树:

  1. 二叉树不会有冲突(collision),这意味着我们能够保证二叉树的插入和查找操作一直都是O(log(n))的时间复杂度。

  2. 二叉树的空间占用跟输入的输入数据一致。所以我们不需要为二叉树预先分配固定的空间。所以,你也不需要预先知道输入数据的size。

  3. 所有的元素在树中是排序好的。

Summary

如果你预先知道输入数据的大小,而且有足够的空间储存哈希表,且不需要对数据进行排序,那么哈希表总是好的。因为哈希表在插入,查找和删除操作中只需要常数时间。

另一方面,如果数据是持续的加入,你预先不知道数据的大小,那么二叉树是一个折中的选择。

Reference:
Hash table vs Binary search tree

转载于:https://www.cnblogs.com/bjwu/p/9823531.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编码Java时的10个微妙的最佳实践

这是10个最佳实践的列表,这些最佳实践比您的平均Josh Bloch有效Java规则要微妙得多。 尽管Josh Bloch的列表很容易学习,并且涉及日常情况,但此处的列表包含了涉及API / SPI设计的较不常见的情况,但可能会产生很大的影响。 我在编…

Vue 实现微信 jssdk 扫码, 上传图片

流程 1: 配置微信公众号JS域名 2:前端发送URL后台获取JSSDK配置, 后台Service代码如下, 修改2处位置: WeixinUtil.APPID > 当前公众号APPID WeixinUtil.getAccessToken() > 当前公众号access_token public interface IWxJssdkService {Map<String, Object> getJssd…

有意思的前端函数面试题

1:考引用类型在比较运算符时候 隐式转换会调用本类型那个方法 toString和valueOf&#xff1f;(去年过年吵的很火国外的题) if(a 1 && a 2 && a 3){console.log("我走进来了"); }<!--答案1:--> var a {num:0}; a.valueOf function(){retur…

用java写个简单的直播强求_全网最简单易懂的Netty入门示例,再不会用Netty我直播吃翔...

//server引导类ServerBootstrap serverBootstrap new ServerBootstrap();//boss 对应 IOServer.java 中的接受新连接线程,主要负责创建新连接NioEventLoopGroup boss new NioEventLoopGroup();//worker 对应 IOServer.java 中的负责读取数据的线程,主要用于读取数据以及业务逻…

XamarinAndroid组件教程设置自定义子元素动画(一)

XamarinAndroid组件教程设置自定义子元素动画(一) 如果在RecyclerViewAnimators.Animators中没有所需要的动画效果&#xff0c;就可以自定义一个。此时&#xff0c;需要让自定义的动画继承BaseItemAnimator抽象类。 【示例1-2】下面以RecylerViewAnimatorsItemAnimator项目为基…

使用Storm进行可扩展的实时状态更新

在本文中&#xff0c;我将说明如何借助Storm框架以可扩展且无锁定的方式在数据库中维护实时事件驱动流程的当前状态。 Storm是基于事件的数据处理引擎。 它的模型依赖于基本原语&#xff0c;例如事件转换&#xff0c;过滤&#xff0c;聚合……&#xff0c;我们将它们组合成拓扑…

python关于字典嵌套字典,列表嵌套字典根据值进行排序

python 对于字典嵌套字典&#xff0c; 列表嵌套字典排序 例&#xff1a;列表嵌套自字典&#xff1a;d [{"name": 张三, s: 68}, {name: 李四, s: 97}] 对于列表嵌套字典可以使用python的sorted()方法&#xff0c;也可以使用list的sort()方法&#xff1a; sorted方法…

【干货】十分钟读懂浏览器渲染流程

在之前写过的一篇《"天龙八步"细说浏览器输入URL后发生了什么》一文中&#xff0c;和大家分享了从在浏览器中输入网址URL到最终页面展示的整个过程。部分读者向我反馈对于最后的浏览器渲染布局这块不是很清晰&#xff0c;所以本文就浏览器渲染流程单独开篇讲解&#…

控制台资费管理主菜单java_java毕业设计_springboot框架的高速公路收费管理系统...

今天介绍一个java毕设题目, 题目内容为springboot框架的高速公路收费管理系统, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 高速公路收费管理系统的信息存储于mysql中, 并基于mybatis进行了orm封装, 该高速公路收费管理…

Hibernate框架的搭建和一个简单的实例

Hibernate是一个支持对JDBC进行封装的框架&#xff0c;实现了对底层数据库访问的封装。非常适合使用和开发。首先需要下载Hibernate&#xff0c;可以在这个网站下载最新包。http://www.hibernate.org/然后打开他的目录结构&#xff0c;将lib目录下的required目录下的包全部导入…

在Amazon EMR上运行Hadoop MapReduce作业

不久前&#xff0c;我发布了如何使用CLI设置EMR群集的信息。 在本文中&#xff0c;我将展示如何使用适用于AWS的Java SDK来设置集群。 展示如何使用Java AWS开发工具包执行此操作的最佳方法是展示完整的示例&#xff0c;因此&#xff0c;让我们开始吧。 设置一个新的Maven项目…

在商城系统开发时遇到商品的多级分类,为增强扩展性,子类可以任意添加,此类问题数据库如何设计...

表结构为&#xff1a; id&#xff08;编号&#xff09; name&#xff08;分类名&#xff09; parentID&#xff08;父类编号&#xff09; 简单举例如下&#xff1a; id name parentID 1 饮料 0&#xff08;为0表示第一大类&#xff09; 2 水果 …

[JSConf EU 2018] 大脑控制 Javascript

先解释&#xff0c;本人为前端菜鸟&#xff0c;之前也未参加过类似的活动&#xff0c;没有翻译过什么文章&#xff0c;此次是好奇心使然&#xff0c;也是想尝试下&#xff0c;学习学习&#xff0c;英文很烂&#xff0c;全靠有道&#xff0c;但是视频整个看下来&#xff0c;还是…

init tarray 太大_[NOIP 2001提高组T4]Car的旅行路线

[题目来源]&#xff1a;NOIP2001提高组T4[关键字]&#xff1a;最短路径[题目大意]&#xff1a;给定平面直角若干个矩形&#xff0c;计算(可经过其他矩形)两个矩形任意顶点间的最短路程费用。//[分析]&#xff1a;其实题目本事没有太大的难点&#xff0c;只需要对每两个点进行连…

Caffe Caffe2入门博客存档

caffe2 教程入门&#xff08;python版&#xff09; https://www.jianshu.com/p/5c0fd1c9fef9?fromtimeline caffe入门学习 https://blog.csdn.net/hjimce/article/details/48933813 运行caffe自带的两个简单例子 https://www.linuxidc.com/Linux/2016-11/136774p9.htm 关于caf…

JavaScript中不得不说的断言?

断言主要应用于“调试”与“测试” 一、前端中的断言 仔细地查找一下JavaScript中的API&#xff0c;实际上并没有多少关于断言的方法。唯一一个就是console.assert&#xff1a; // console.assert(condition, message)const a 1console.assert(typeof a number, a should be…

Java EE状态会话Bean(EJB)示例

在本文中&#xff0c;我们将了解如何在简单的Web应用程序中使用状态会话Bean来跟踪客户端会话中的状态。 1.简介 有状态会话Bean通常保存有关特定客户端会话的信息&#xff0c;并在整个会话中保留该信息&#xff08;与无状态会话Bean相对&#xff09;。 有状态EJB实例仅与一个…

计算机科学速成课16:软件工程

概念&#xff1a;建造标准或者大型软件的方法和工具代码打包成函数 面向过程函数打包成对象 面向对象对象层层打包Car.Engine.CruiseControl.SetCruiseSpeed(55)应用程序接口api集成开发环境IDE&#xff1a;code&#xff0c;整理&#xff0c;编译&#xff0c;测试注释和readme文…

牛客网NOIP赛前集训营-提高组(第六场)B-选择题[背包]

题意 题目链接 分析 直接背包之后可以 \(O(n)\) 去除一个物品的影响。注意特判 \([p1]\) 的情况。总时间复杂度为 \(O(n^2)\) 。代码 #include<bits/stdc.h> using namespace std; #define go(u) for(int ihead[u],ve[i].to;i;ie[i].last,ve[i].to) #define rep(i,a,b) f…

起点海外版 Hybrid App-内嵌页优化实践

本文作者&#xff1a;刘文涛 原创声明&#xff1a;本文为阅文前端团队 YFE 成员出品&#xff0c;请尊重原创&#xff0c;转载请联系公众号 (id: yuewen_YFE) 获取授权&#xff0c;并注明作者、出处和链接。 今年年初我司开启了起点品牌的海外之旅&#xff0c;名为「 Webnovel 」…