动态数据结构总结与比较

 
Category: DSA

这里首先解释一下什么是动态数据结构:动态数据结构是支持动态的更新操作,里面存储的数据是时刻在变化的,通俗一点讲,它不仅仅支持查询,还支持删除、插入数据。而且,这些操作都非常高效。如果不高效,也就算不上是有效的动态数据结构了。所以,这里的红黑树算一个,支持动态的插入、删除、查找,而且效率都很高。链表、队列、栈实际上算不上,因为操作非常有限,查询效率不高。

答:

  1. 散列表:插入删除查找都是O(1),是最常用的,但其缺点是不能顺序遍历以及扩容缩容的性能损耗。适用于那些不需要顺序遍历,数据更新不那么频繁的,查找比较频繁的。
  2. 跳表:插入删除查找都是O(logn),并且能顺序遍历。缺点是空间复杂度O(n)。适用于不那么在意内存空间的,其顺序遍历和区间查找非常方便。
  3. 红黑树:插入删除查找都是O(logn),中序遍历即是顺序遍历,稳定。缺点是难以实现,去查找不方便。其实跳表更佳,但红黑树已经用于很多地方了。

B和B+主要用在文件系统以及数据库中做索引等,比如Mysql:B-Tree Index in MySql

trie 树的一个典型应用是前缀匹配,比如下面这个很常见的场景,在我们输入时,搜索引擎会给予提示 还有比如IP选路,也是前缀匹配,一定程度会用到trie

B和B+主要用在文件系统以及数据库中做索引等,比如Mysql:B-Tree Index in MySql trie 树的一个典型应用是前缀匹配,比如下面这个很常见的场景,在我们输入时,搜索引擎会给予提示 还有比如IP选路,也是前缀匹配,一定程度会用到trie

跳表:Redis中就使用跳表,而不是红黑树来存储管理其中的元素(应该说的是一级元素-直接的Key,里面的value应该是有不同的数据结构)。 首先,跳表是skiplist?不是ziplist。ziplist在redis中是一个非常省内存的链表(代价是性能略低),所以在hash元素的个数很少(比如只有几十个), 那么用这个结构来存储则可以在性能损失很小的情况下节约很多内存(redis是内存数据库啊,能省还是要省的)。好这个问题清楚了。 在server端,对并发和性能有要求的情况下,如何选择合适的数据结构(这里是跳跃表和红黑树)。 如果单纯比较性能,跳跃表和红黑树可以说相差不大,但是加上并发的环境就不一样了, 如果要更新数据,跳跃表需要更新的部分就比较少,锁的东西也就比较少,所以不同线程争锁的代价就相对少了, 而红黑树有个平衡的过程,牵涉到大量的节点,争锁的代价也就相对较高了。性能也就不如前者了。 在并发环境下skiplist有另外一个优势,红黑树在插入和删除的时候可能需要做一些rebalance的操作,这样的操作可能会涉及到整个树的其他部分, 而skiplist的操作显然更加局部性一些,锁需要盯住的节点更少,因此在这样的情况下性能好一些。