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


    二叉树(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

  • 相关阅读:
    u-boot.lds分析
    u-boot的makefile中的一些目录的设定,以及涉及的shell,make语法。
    u-boot入门第一步,分析mkconfig
    uboot学习——Makefile里的echo使用!
    Linux下的打包与压缩和tar命令!
    关于undefined reference的问题
    JZ2440 编译Uboot1.1.6 undefined reference to ‘raise’
    POJ 1094 Sorting It All Out
    链式前向星
    Codeforces Round #197 (Div. 2) A~D
  • 原文地址:https://www.cnblogs.com/bjwu/p/9823531.html
Copyright © 2020-2023  润新知