分析线性表、二叉平衡树和哈希表存储数据时各自的优劣

链接:https://www.nowcoder.com/questionTerminal/b67ebdf7e1a84f37a9b1ed578525f625
 

线性表,插入的时间复杂度为O(1),但是因内部无法保证有序,所以查找需要O(Length)的时间复杂度,而删除则取决于所用实现是链表还是数组,链表为O(1),数组为O(Length)。虽然时间复杂度看起来比较糟糕,但是其时间常数相对后两者很小,比较适合于数据量极其小(<=100)、查询量也极其小的情况。

二叉平衡树,不论是插入、查询还是删除,均摊时间复杂度均近似为O(logn),时间表现较稳定也较有效率,但是依赖于旋转操作来维持平衡(也有不需要旋转操作的二叉平衡树,但是工业上的主流实现选择还是红黑树,目前红黑树仍然被认为是时间效率最优的二叉平衡树,在随机数据下的确远优于Treap、Splay和AVL),每次操作需要的运算很多,常数很大,在数据量大且随机的情况下并不如hash。

Hash表,在完全随机的情况下,插入、查询和删除都可以认为是O(1)的时间复杂度(无冲突),有hash的常数存在但是好于二叉平衡树。但是hash在黑客恶意构造数据的情况下很可能会出现大量的冲突,导致hash表的查询等操作的时间复杂度成最坏情况O(n),曾有被黑客用于恶意拒绝服务攻击的例子。而且hash表的内存消耗要比较大才能减少冲突,保证其性能表现。但是这仍然不妨碍hash表是目前工业界一种很流行的,在面对大量数据进行插入、查询、删除时选用的数据结构。

 

对于优劣势,一方面考虑存储,一方面考虑性能:

线性表:可以用顺序表和链表实现,而且存储结构不一样,性能也不一样,总的来说线性表的优势是结构简单,访问节点比较快,对单节点的操作比较简单;适合于小数据量的存储,并且访问不存在经常变化的需求;

散列表:实现了随机访问,所以性能比较快,但是对于散列函数的设计要求比较高,而且设计需要根据自己的需求进行设计,实现高访问;

二叉平衡树:比较灵活,在空间上可以实现高效压缩存储,但是对于节点的操作比较复杂

接触堆数据结构是在排序里面讲的,空间复杂度O(1),时间复杂度O(NlogN),但是在实践中还是不如快速排序(好像快速排序可以更好的利用硬件特性)。堆 的意义就在于:最快的找到最大/最小值,在堆结构中插入一个值重新构造堆结构,取走最大/最下值后重新构造堆结构 其时间复杂度为O(logN),而其他方法最少为O(N).堆实践中用途不在于排序,其主要用在调度算法中,比如优先级调度,每次取优先级最高的,时间驱 动,取时间最小/等待最长的 等等 ,分为最大堆/最小堆。

哈希表主要可以在O(1)时间内对查找对象定位,但是事实上,如果输入集合不确定的情况下,可能出现大量的冲突,虽然有很多好的哈希函数,但是随着随机输入,大量冲突还是不可避免,可能出现最差情况。所以,哈希表如果用在输入集合确定(即以后只会做查询操作)的情况下,选择合适的函数函数和解决冲突的方法(perfect hash)可以在O(1)时间内完成查找(有证明,看不懂)。 (装填因子)

二叉树支持动态的插入和查找,保证操作在O(height)时间,这就是完成了哈希表不便完成的工作,动态性。但是二叉树有可能出现worst-case,如果输入序列已经排序,则时间复杂度为O(N)

平衡二叉树/红黑树就是为了将查找的时间复杂度保证在O(logN)范围内。

所以如果输入结合确定,所需要的就是查询,则可以考虑使用哈希表,如果输入集合不确定,则考虑使用平衡二叉树/红黑树,保证达到最大效率

你可能感兴趣的:(C语言)